Merge "Update anomaly report UUID" into tm-qpr-dev am: 1d20bc7b47

Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/opt/telephony/+/20390283

Change-Id: Ida82a342d02ff0d00952217ccc0cc4b04601ee72
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
diff --git a/OWNERS b/OWNERS
index 94509fe..1c2928e 100644
--- a/OWNERS
+++ b/OWNERS
@@ -14,8 +14,14 @@
 sasindran@google.com
 tgunn@google.com
 tjstuart@google.com
+tnd@google.com
 xiaotonj@google.com
 
+# Temporarily reduced the owner during refactoring
+per-file SubscriptionController.java=set noparent
+per-file SubscriptionController.java=jackyu@google.com,amruthr@google.com
+per-file SubscriptionInfoUpdater.java=set noparent
+per-file SubscriptionInfoUpdater.java=jackyu@google.com,amruthr@google.com
 
 
 
diff --git a/proto/src/persist_atoms.proto b/proto/src/persist_atoms.proto
index 6a75c3f..3a79cdc 100644
--- a/proto/src/persist_atoms.proto
+++ b/proto/src/persist_atoms.proto
@@ -190,10 +190,10 @@
 // NOTE: StatsLog functions use int in place of enum
 
 message VoiceCallSession {
+    reserved 4;
     optional int32 bearer_at_start = 1;
     optional int32 bearer_at_end = 2;
     optional int32 direction = 3;
-    optional int32 setup_duration = 4;
     optional bool setup_failed = 5;
     optional int32 disconnect_reason_code = 6;
     optional int32 disconnect_extra_code = 7;
diff --git a/src/java/com/android/internal/telephony/CarrierActionAgent.java b/src/java/com/android/internal/telephony/CarrierActionAgent.java
index 42a4f23..6d74c18 100644
--- a/src/java/com/android/internal/telephony/CarrierActionAgent.java
+++ b/src/java/com/android/internal/telephony/CarrierActionAgent.java
@@ -27,6 +27,7 @@
 import android.os.RegistrantList;
 import android.provider.Settings;
 import android.provider.Telephony;
+import android.telephony.SubscriptionManager;
 import android.telephony.TelephonyManager;
 import android.util.LocalLog;
 import android.util.Log;
@@ -93,7 +94,11 @@
                     // ignore rebroadcast since carrier apps are direct boot aware.
                     return;
                 }
-                sendMessage(obtainMessage(EVENT_SIM_STATE_CHANGED, iccState));
+                final int phoneId = intent.getIntExtra(PhoneConstants.PHONE_KEY,
+                        SubscriptionManager.INVALID_PHONE_INDEX);
+                if (mPhone.getPhoneId() == phoneId) {
+                    sendMessage(obtainMessage(EVENT_SIM_STATE_CHANGED, iccState));
+                }
             }
         }
     };
diff --git a/src/java/com/android/internal/telephony/CarrierSignalAgent.java b/src/java/com/android/internal/telephony/CarrierSignalAgent.java
index 2914ff9..8509c5e 100644
--- a/src/java/com/android/internal/telephony/CarrierSignalAgent.java
+++ b/src/java/com/android/internal/telephony/CarrierSignalAgent.java
@@ -48,7 +48,6 @@
 
 import java.io.FileDescriptor;
 import java.io.PrintWriter;
-import java.util.Arrays;
 import java.util.HashMap;
 import java.util.HashSet;
 import java.util.Map;
@@ -102,26 +101,24 @@
     /**
      * This is a list of supported signals from CarrierSignalAgent
      */
-    private static final Set<String> VALID_CARRIER_SIGNAL_ACTIONS = new HashSet<>(Arrays.asList(
+    private static final Set<String> VALID_CARRIER_SIGNAL_ACTIONS = Set.of(
             TelephonyManager.ACTION_CARRIER_SIGNAL_PCO_VALUE,
             TelephonyManager.ACTION_CARRIER_SIGNAL_REDIRECTED,
             TelephonyManager.ACTION_CARRIER_SIGNAL_REQUEST_NETWORK_FAILED,
             TelephonyManager.ACTION_CARRIER_SIGNAL_RESET,
-            TelephonyManager.ACTION_CARRIER_SIGNAL_DEFAULT_NETWORK_AVAILABLE));
+            TelephonyManager.ACTION_CARRIER_SIGNAL_DEFAULT_NETWORK_AVAILABLE);
 
-    private static final Map<String, String> NEW_ACTION_TO_COMPAT_MAP =
-            new HashMap<String, String>() {{
-                put(TelephonyManager.ACTION_CARRIER_SIGNAL_PCO_VALUE,
-                        TelephonyIntents.ACTION_CARRIER_SIGNAL_PCO_VALUE);
-                put(TelephonyManager.ACTION_CARRIER_SIGNAL_REDIRECTED,
-                        TelephonyIntents.ACTION_CARRIER_SIGNAL_REDIRECTED);
-                put(TelephonyManager.ACTION_CARRIER_SIGNAL_REQUEST_NETWORK_FAILED,
-                        TelephonyIntents.ACTION_CARRIER_SIGNAL_REQUEST_NETWORK_FAILED);
-                put(TelephonyManager.ACTION_CARRIER_SIGNAL_RESET,
-                        TelephonyIntents.ACTION_CARRIER_SIGNAL_RESET);
-                put(TelephonyManager.ACTION_CARRIER_SIGNAL_DEFAULT_NETWORK_AVAILABLE,
-                        TelephonyIntents.ACTION_CARRIER_SIGNAL_DEFAULT_NETWORK_AVAILABLE);
-            }};
+    private static final Map<String, String> NEW_ACTION_TO_COMPAT_MAP = Map.of(
+            TelephonyManager.ACTION_CARRIER_SIGNAL_PCO_VALUE,
+                    TelephonyIntents.ACTION_CARRIER_SIGNAL_PCO_VALUE,
+            TelephonyManager.ACTION_CARRIER_SIGNAL_REDIRECTED,
+                    TelephonyIntents.ACTION_CARRIER_SIGNAL_REDIRECTED,
+            TelephonyManager.ACTION_CARRIER_SIGNAL_REQUEST_NETWORK_FAILED,
+                    TelephonyIntents.ACTION_CARRIER_SIGNAL_REQUEST_NETWORK_FAILED,
+            TelephonyManager.ACTION_CARRIER_SIGNAL_RESET,
+                    TelephonyIntents.ACTION_CARRIER_SIGNAL_RESET,
+            TelephonyManager.ACTION_CARRIER_SIGNAL_DEFAULT_NETWORK_AVAILABLE,
+                    TelephonyIntents.ACTION_CARRIER_SIGNAL_DEFAULT_NETWORK_AVAILABLE);
 
     private static final Map<String, String> COMPAT_ACTION_TO_NEW_MAP = NEW_ACTION_TO_COMPAT_MAP
             .entrySet().stream().collect(Collectors.toMap(Map.Entry::getValue, Map.Entry::getKey));
diff --git a/src/java/com/android/internal/telephony/IccSmsInterfaceManager.java b/src/java/com/android/internal/telephony/IccSmsInterfaceManager.java
index a329771..d3e6a0d 100644
--- a/src/java/com/android/internal/telephony/IccSmsInterfaceManager.java
+++ b/src/java/com/android/internal/telephony/IccSmsInterfaceManager.java
@@ -625,9 +625,9 @@
         }
 
         if (Rlog.isLoggable("SMS", Log.VERBOSE)) {
-            log("pdu: " + pdu +
-                "\n format=" + format +
-                "\n receivedIntent=" + receivedIntent);
+            log("pdu: " + IccUtils.bytesToHexString(pdu)
+                    + "\n format=" + format
+                    + "\n receivedIntent=" + receivedIntent);
         }
         mDispatchersController.injectSmsPdu(pdu, format, false /* isOverIms */,
                 result -> {
diff --git a/src/java/com/android/internal/telephony/InboundSmsHandler.java b/src/java/com/android/internal/telephony/InboundSmsHandler.java
index eeda1f9..8f43dce 100644
--- a/src/java/com/android/internal/telephony/InboundSmsHandler.java
+++ b/src/java/com/android/internal/telephony/InboundSmsHandler.java
@@ -89,7 +89,6 @@
 import java.lang.annotation.RetentionPolicy;
 import java.util.ArrayList;
 import java.util.Arrays;
-import java.util.HashMap;
 import java.util.List;
 import java.util.ListIterator;
 import java.util.Map;
@@ -116,38 +115,6 @@
     protected static final boolean DBG = true;
     protected static final boolean VDBG = false; // STOPSHIP if true, logs user data
 
-    /** Query projection for checking for duplicate message segments. */
-    private static final String[] PDU_DELETED_FLAG_PROJECTION = {
-            "pdu",
-            "deleted"
-    };
-
-    /** Mapping from DB COLUMN to PDU_SEQUENCE_PORT PROJECTION index */
-    private static final Map<Integer, Integer> PDU_DELETED_FLAG_PROJECTION_INDEX_MAPPING =
-            new HashMap<Integer, Integer>() {{
-            put(PDU_COLUMN, 0);
-            put(DELETED_FLAG_COLUMN, 1);
-            }};
-
-    /** Query projection for combining concatenated message segments. */
-    private static final String[] PDU_SEQUENCE_PORT_PROJECTION = {
-            "pdu",
-            "sequence",
-            "destination_port",
-            "display_originating_addr",
-            "date"
-    };
-
-    /** Mapping from DB COLUMN to PDU_SEQUENCE_PORT PROJECTION index */
-    private static final Map<Integer, Integer> PDU_SEQUENCE_PORT_PROJECTION_INDEX_MAPPING =
-            new HashMap<Integer, Integer>() {{
-                put(PDU_COLUMN, 0);
-                put(SEQUENCE_COLUMN, 1);
-                put(DESTINATION_PORT_COLUMN, 2);
-                put(DISPLAY_ADDRESS_COLUMN, 3);
-                put(DATE_COLUMN, 4);
-    }};
-
     public static final int PDU_COLUMN = 0;
     public static final int SEQUENCE_COLUMN = 1;
     public static final int DESTINATION_PORT_COLUMN = 2;
@@ -161,6 +128,34 @@
     public static final int DELETED_FLAG_COLUMN = 10;
     public static final int SUBID_COLUMN = 11;
 
+    /** Query projection for checking for duplicate message segments. */
+    private static final String[] PDU_DELETED_FLAG_PROJECTION = {
+            "pdu",
+            "deleted"
+    };
+
+    /** Mapping from DB COLUMN to PDU_SEQUENCE_PORT PROJECTION index */
+    private static final Map<Integer, Integer> PDU_DELETED_FLAG_PROJECTION_INDEX_MAPPING = Map.of(
+            PDU_COLUMN, 0,
+            DELETED_FLAG_COLUMN, 1);
+
+    /** Query projection for combining concatenated message segments. */
+    private static final String[] PDU_SEQUENCE_PORT_PROJECTION = {
+            "pdu",
+            "sequence",
+            "destination_port",
+            "display_originating_addr",
+            "date"
+    };
+
+    /** Mapping from DB COLUMN to PDU_SEQUENCE_PORT PROJECTION index */
+    private static final Map<Integer, Integer> PDU_SEQUENCE_PORT_PROJECTION_INDEX_MAPPING = Map.of(
+            PDU_COLUMN, 0,
+            SEQUENCE_COLUMN, 1,
+            DESTINATION_PORT_COLUMN, 2,
+            DISPLAY_ADDRESS_COLUMN, 3,
+            DATE_COLUMN, 4);
+
     public static final String SELECT_BY_ID = "_id=?";
 
     /** New SMS received as an AsyncResult. */
diff --git a/src/java/com/android/internal/telephony/NitzData.java b/src/java/com/android/internal/telephony/NitzData.java
index 6b19e08..8430585 100644
--- a/src/java/com/android/internal/telephony/NitzData.java
+++ b/src/java/com/android/internal/telephony/NitzData.java
@@ -21,6 +21,7 @@
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.telephony.Rlog;
 
+import java.time.DateTimeException;
 import java.time.LocalDateTime;
 import java.time.ZoneOffset;
 import java.util.Objects;
@@ -39,9 +40,6 @@
     private static final int MS_PER_QUARTER_HOUR = 15 * 60 * 1000;
     private static final int MS_PER_HOUR = 60 * 60 * 1000;
 
-    /* Time stamp after 19 January 2038 is not supported under 32 bit */
-    private static final int MAX_NITZ_YEAR = 2037;
-
     private static final Pattern NITZ_SPLIT_PATTERN = Pattern.compile("[/:,+-]");
 
     // Stored For logging / debugging only.
@@ -77,22 +75,37 @@
         try {
             String[] nitzSubs = NITZ_SPLIT_PATTERN.split(nitz);
 
-            int year = 2000 + Integer.parseInt(nitzSubs[0]);
-            if (year > MAX_NITZ_YEAR) {
-                if (ServiceStateTracker.DBG) {
-                    Rlog.e(LOG_TAG, "NITZ year: " + year + " exceeds limit, skip NITZ time update");
-                }
-                return null;
+            int year = Integer.parseInt(nitzSubs[0]);
+            if (year < 1 || year > 99) {
+                // 0 > year > 99 imply an invalid string.
+                //
+                // At the time of this comment (year 2023), a zero year is considered invalid and
+                // assumed to be the result of invalid data being converted to zero in the code that
+                // turns the binary NITZ into a string. For the next few decades at least, Android
+                // devices should not need to interpret zero. Hopefully, NITZ will be replaced by
+                // the time that's not true, or folks dealing the Y2K1 issue can handle it.
+                //
+                // DateTimeException is also thrown by LocalDateTime below if the values are out of
+                // range and will be handled in the catch block.
+                throw new DateTimeException("Invalid NITZ year == 0");
             }
 
+            // Values < {current year} could be considered invalid but are used in test code, so no
+            // window is applied to adjust low values < {current year} with "+ 2100" (and would also
+            // need to consider zero as valid). Code that processes the NitzData is in a better
+            // position to log and discard obviously invalid NITZ signals from past years.
+            year += 2000;
+
             int month = Integer.parseInt(nitzSubs[1]);
             int date = Integer.parseInt(nitzSubs[2]);
             int hour = Integer.parseInt(nitzSubs[3]);
             int minute = Integer.parseInt(nitzSubs[4]);
             int second = Integer.parseInt(nitzSubs[5]);
 
-            /* NITZ time (hour:min:sec) will be in UTC but it supplies the timezone
-             * offset as well (which we won't worry about until later) */
+            // NITZ time (hour:min:sec) will be in UTC but it supplies the timezone
+            // offset as well (which we won't worry about until later).
+            // The LocalDateTime.of() will throw DateTimeException for values outside the allowed
+            // range for the Gregorian calendar.
             long epochMillis = LocalDateTime.of(year, month, date, hour, minute, second)
                     .toInstant(ZoneOffset.UTC)
                     .toEpochMilli();
diff --git a/src/java/com/android/internal/telephony/RadioSimProxy.java b/src/java/com/android/internal/telephony/RadioSimProxy.java
index c7e19c4..da5b660 100644
--- a/src/java/com/android/internal/telephony/RadioSimProxy.java
+++ b/src/java/com/android/internal/telephony/RadioSimProxy.java
@@ -576,7 +576,7 @@
                 halImsiInfo.base.expirationTime = imsiEncryptionInfo.getExpirationTime().getTime();
             }
             for (byte b : imsiEncryptionInfo.getPublicKey().getEncoded()) {
-                halImsiInfo.base.carrierKey.add(new Byte(b));
+                halImsiInfo.base.carrierKey.add(Byte.valueOf(b));
             }
             halImsiInfo.keyType = (byte) imsiEncryptionInfo.getKeyType();
 
@@ -592,7 +592,7 @@
                 halImsiInfo.expirationTime = imsiEncryptionInfo.getExpirationTime().getTime();
             }
             for (byte b : imsiEncryptionInfo.getPublicKey().getEncoded()) {
-                halImsiInfo.carrierKey.add(new Byte(b));
+                halImsiInfo.carrierKey.add(Byte.valueOf(b));
             }
 
             ((android.hardware.radio.V1_1.IRadio) mRadioProxy).setCarrierInfoForImsiEncryption(
diff --git a/src/java/com/android/internal/telephony/ServiceStateTracker.java b/src/java/com/android/internal/telephony/ServiceStateTracker.java
index 3ed4578..0f2991b 100755
--- a/src/java/com/android/internal/telephony/ServiceStateTracker.java
+++ b/src/java/com/android/internal/telephony/ServiceStateTracker.java
@@ -3464,14 +3464,15 @@
         useDataRegStateForDataOnlyDevices();
         processIwlanRegistrationInfo();
 
+        updateNrFrequencyRangeFromPhysicalChannelConfigs(mLastPhysicalChannelConfigList, mNewSS);
+        updateNrStateFromPhysicalChannelConfigs(mLastPhysicalChannelConfigList, mNewSS);
+
         if (TelephonyUtils.IS_DEBUGGABLE && mPhone.mTelephonyTester != null) {
             mPhone.mTelephonyTester.overrideServiceState(mNewSS);
         }
 
         NetworkRegistrationInfo networkRegState = mNewSS.getNetworkRegistrationInfo(
                 NetworkRegistrationInfo.DOMAIN_PS, AccessNetworkConstants.TRANSPORT_TYPE_WWAN);
-        updateNrFrequencyRangeFromPhysicalChannelConfigs(mLastPhysicalChannelConfigList, mNewSS);
-        updateNrStateFromPhysicalChannelConfigs(mLastPhysicalChannelConfigList, mNewSS);
         setPhyCellInfoFromCellIdentity(mNewSS, networkRegState.getCellIdentity());
 
         if (DBG) {
@@ -5358,8 +5359,7 @@
         pw.println(" mNewSS=" + mNewSS);
         pw.println(" mVoiceCapable=" + mVoiceCapable);
         pw.println(" mRestrictedState=" + mRestrictedState);
-        pw.println(" mPollingContext=" + mPollingContext + " - " +
-                (mPollingContext != null ? mPollingContext[0] : ""));
+        pw.println(" mPollingContext=" + Arrays.toString(mPollingContext));
         pw.println(" mDesiredPowerState=" + mDesiredPowerState);
         pw.println(" mRestrictedState=" + mRestrictedState);
         pw.println(" mPendingRadioPowerOffAfterDataOff=" + mPendingRadioPowerOffAfterDataOff);
@@ -5397,8 +5397,8 @@
         pw.println(" mDefaultRoamingIndicator=" + mDefaultRoamingIndicator);
         pw.println(" mRegistrationState=" + mRegistrationState);
         pw.println(" mMdn=" + mMdn);
-        pw.println(" mHomeSystemId=" + mHomeSystemId);
-        pw.println(" mHomeNetworkId=" + mHomeNetworkId);
+        pw.println(" mHomeSystemId=" + Arrays.toString(mHomeSystemId));
+        pw.println(" mHomeNetworkId=" + Arrays.toString(mHomeNetworkId));
         pw.println(" mMin=" + mMin);
         pw.println(" mPrlVersion=" + mPrlVersion);
         pw.println(" mIsMinInfoReady=" + mIsMinInfoReady);
diff --git a/src/java/com/android/internal/telephony/SmsBroadcastUndelivered.java b/src/java/com/android/internal/telephony/SmsBroadcastUndelivered.java
index 7c52a42..f5d9e9e 100644
--- a/src/java/com/android/internal/telephony/SmsBroadcastUndelivered.java
+++ b/src/java/com/android/internal/telephony/SmsBroadcastUndelivered.java
@@ -16,6 +16,8 @@
 
 package com.android.internal.telephony;
 
+import static java.util.Map.entry;
+
 import android.compat.annotation.UnsupportedAppUsage;
 import android.content.BroadcastReceiver;
 import android.content.ContentResolver;
@@ -72,19 +74,18 @@
 
     /** Mapping from DB COLUMN to PDU_PENDING_MESSAGE_PROJECTION index */
     static final Map<Integer, Integer> PDU_PENDING_MESSAGE_PROJECTION_INDEX_MAPPING =
-            new HashMap<Integer, Integer>() {{
-                put(InboundSmsHandler.PDU_COLUMN, 0);
-                put(InboundSmsHandler.SEQUENCE_COLUMN, 1);
-                put(InboundSmsHandler.DESTINATION_PORT_COLUMN, 2);
-                put(InboundSmsHandler.DATE_COLUMN, 3);
-                put(InboundSmsHandler.REFERENCE_NUMBER_COLUMN, 4);
-                put(InboundSmsHandler.COUNT_COLUMN, 5);
-                put(InboundSmsHandler.ADDRESS_COLUMN, 6);
-                put(InboundSmsHandler.ID_COLUMN, 7);
-                put(InboundSmsHandler.MESSAGE_BODY_COLUMN, 8);
-                put(InboundSmsHandler.DISPLAY_ADDRESS_COLUMN, 9);
-                put(InboundSmsHandler.SUBID_COLUMN, 10);
-            }};
+            Map.ofEntries(
+                entry(InboundSmsHandler.PDU_COLUMN, 0),
+                entry(InboundSmsHandler.SEQUENCE_COLUMN, 1),
+                entry(InboundSmsHandler.DESTINATION_PORT_COLUMN, 2),
+                entry(InboundSmsHandler.DATE_COLUMN, 3),
+                entry(InboundSmsHandler.REFERENCE_NUMBER_COLUMN, 4),
+                entry(InboundSmsHandler.COUNT_COLUMN, 5),
+                entry(InboundSmsHandler.ADDRESS_COLUMN, 6),
+                entry(InboundSmsHandler.ID_COLUMN, 7),
+                entry(InboundSmsHandler.MESSAGE_BODY_COLUMN, 8),
+                entry(InboundSmsHandler.DISPLAY_ADDRESS_COLUMN, 9),
+                entry(InboundSmsHandler.SUBID_COLUMN, 10));
 
 
     private static SmsBroadcastUndelivered instance;
diff --git a/src/java/com/android/internal/telephony/SmsStorageMonitor.java b/src/java/com/android/internal/telephony/SmsStorageMonitor.java
index b890a4d..2375c73 100755
--- a/src/java/com/android/internal/telephony/SmsStorageMonitor.java
+++ b/src/java/com/android/internal/telephony/SmsStorageMonitor.java
@@ -29,6 +29,7 @@
 import android.provider.Telephony.Sms.Intents;
 import android.telephony.SubscriptionManager;
 
+import com.android.internal.annotations.VisibleForTesting;
 import com.android.telephony.Rlog;
 
 /**
@@ -41,14 +42,26 @@
 public class SmsStorageMonitor extends Handler {
     private static final String TAG = "SmsStorageMonitor";
 
+    /** Maximum number of times to retry memory status reporting */
+    private static final int MAX_RETRIES = 1;
+
+    /** Delay before next attempt on a failed memory status reporting, in milliseconds. */
+    private static final int RETRY_DELAY = 5000; // 5 seconds
+
     /** SIM/RUIM storage is full */
     private static final int EVENT_ICC_FULL = 1;
 
+    /** Report memory status */
+    private static final int EVENT_REPORT_MEMORY_STATUS = 2;
+
     /** Memory status reporting is acknowledged by RIL */
-    private static final int EVENT_REPORT_MEMORY_STATUS_DONE = 2;
+    private static final int EVENT_REPORT_MEMORY_STATUS_DONE = 3;
+
+    /** Retry memory status reporting */
+    private static final int EVENT_RETRY_MEMORY_STATUS_REPORTING = 4;
 
     /** Radio is ON */
-    private static final int EVENT_RADIO_ON = 3;
+    private static final int EVENT_RADIO_ON = 5;
 
     /** Context from phone object passed to constructor. */
     private final Context mContext;
@@ -56,14 +69,19 @@
     /** Wake lock to ensure device stays awake while dispatching the SMS intent. */
     private PowerManager.WakeLock mWakeLock;
 
-    private boolean mReportMemoryStatusPending;
+    private int mMaxRetryCount = MAX_RETRIES;
+    private int mRetryDelay = RETRY_DELAY;
+    private int mRetryCount = 0;
+    private boolean mIsWaitingResponse = false;
+    private boolean mNeedNewReporting = false;
+    private boolean mIsMemoryStatusReportingFailed = false;
 
     /** it is use to put in to extra value for SIM_FULL_ACTION and SMS_REJECTED_ACTION */
     Phone mPhone;
 
     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
-    final CommandsInterface mCi;                            // accessed from inner class
-    boolean mStorageAvailable = true;                       // accessed from inner class
+    final CommandsInterface mCi;
+    boolean mStorageAvailable = true;
 
     /**
      * Hold the wake lock for 5 seconds, which should be enough time for
@@ -93,6 +111,16 @@
         mContext.registerReceiver(mResultReceiver, filter);
     }
 
+    @VisibleForTesting
+    public void setMaxRetries(int maxCount) {
+        mMaxRetryCount = maxCount;
+    }
+
+    @VisibleForTesting
+    public void setRetryDelayInMillis(int delay) {
+        mRetryDelay = delay;
+    }
+
     public void dispose() {
         mCi.unSetOnIccSmsFull(this);
         mCi.unregisterForOn(this);
@@ -105,35 +133,85 @@
      */
     @Override
     public void handleMessage(Message msg) {
-        AsyncResult ar;
+        boolean isAvailable = mStorageAvailable;
 
         switch (msg.what) {
             case EVENT_ICC_FULL:
                 handleIccFull();
                 break;
 
-            case EVENT_REPORT_MEMORY_STATUS_DONE:
-                ar = (AsyncResult) msg.obj;
-                if (ar.exception != null) {
-                    mReportMemoryStatusPending = true;
-                    Rlog.v(TAG, "Memory status report to modem pending : mStorageAvailable = "
-                            + mStorageAvailable);
+            case EVENT_REPORT_MEMORY_STATUS:
+                if (mIsWaitingResponse) {
+                    Rlog.v(TAG, "EVENT_REPORT_MEMORY_STATUS - deferred");
+                    // Previous reporting is on-going now. New reporting will be issued in
+                    // EVENT_REPORT_MEMORY_STATUS_DONE.
+                    mNeedNewReporting = true;
                 } else {
-                    mReportMemoryStatusPending = false;
+                    Rlog.v(TAG, "EVENT_REPORT_MEMORY_STATUS - report sms memory status"
+                            + (isAvailable ? "(not full)" : "(full)"));
+                    // Clear a delayed EVENT_RETRY_MEMORY_STATUS_REPORTING
+                    // and mIsMemoryStatusReportingFailed.
+                    removeMessages(EVENT_RETRY_MEMORY_STATUS_REPORTING);
+                    mIsMemoryStatusReportingFailed = false;
+                    mRetryCount = 0;
+                    sendMemoryStatusReport(isAvailable);
                 }
                 break;
 
+            case EVENT_REPORT_MEMORY_STATUS_DONE:
+                AsyncResult ar = (AsyncResult) msg.obj;
+                mIsWaitingResponse = false;
+                Rlog.v(TAG, "EVENT_REPORT_MEMORY_STATUS_DONE - "
+                        + (ar.exception == null ? "succeeded" : "failed"));
+                if (mNeedNewReporting) {
+                    Rlog.v(TAG, "EVENT_REPORT_MEMORY_STATUS_DONE - report again now"
+                            + (isAvailable ? "(not full)" : "(full)"));
+                    // New reportings have been requested, report last memory status here.
+                    mNeedNewReporting = false;
+                    mRetryCount = 0;
+                    sendMemoryStatusReport(isAvailable);
+                } else {
+                    if (ar.exception != null) {
+                        if (mRetryCount++ < mMaxRetryCount) {
+                            Rlog.v(TAG, "EVENT_REPORT_MEMORY_STATUS_DONE - retry in "
+                                    + mRetryDelay + "ms");
+                            sendMessageDelayed(
+                                    obtainMessage(EVENT_RETRY_MEMORY_STATUS_REPORTING),
+                                    mRetryDelay);
+                        } else {
+                            Rlog.v(TAG, "EVENT_REPORT_MEMORY_STATUS_DONE - "
+                                    + "no retry anymore(pended)");
+                            mRetryCount = 0;
+                            mIsMemoryStatusReportingFailed = true;
+                        }
+                    } else {
+                        mRetryCount = 0;
+                        mIsMemoryStatusReportingFailed = false;
+                    }
+                }
+                break;
+
+            case EVENT_RETRY_MEMORY_STATUS_REPORTING:
+                Rlog.v(TAG, "EVENT_RETRY_MEMORY_STATUS_REPORTING - retry"
+                        + (isAvailable ? "(not full)" : "(full)"));
+                sendMemoryStatusReport(isAvailable);
+                break;
+
             case EVENT_RADIO_ON:
-                if (mReportMemoryStatusPending) {
-                    Rlog.v(TAG, "Sending pending memory status report : mStorageAvailable = "
-                            + mStorageAvailable);
-                    mCi.reportSmsMemoryStatus(mStorageAvailable,
-                            obtainMessage(EVENT_REPORT_MEMORY_STATUS_DONE));
+                if (mIsMemoryStatusReportingFailed) {
+                    Rlog.v(TAG, "EVENT_RADIO_ON - report failed sms memory status"
+                            + (isAvailable ? "(not full)" : "(full)"));
+                    sendMemoryStatusReport(isAvailable);
                 }
                 break;
         }
     }
 
+    private void sendMemoryStatusReport(boolean isAvailable) {
+        mIsWaitingResponse = true;
+        mCi.reportSmsMemoryStatus(isAvailable, obtainMessage(EVENT_REPORT_MEMORY_STATUS_DONE));
+    }
+
     private void createWakelock() {
         PowerManager pm = (PowerManager)mContext.getSystemService(Context.POWER_SERVICE);
         mWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "SmsStorageMonitor");
@@ -161,12 +239,12 @@
     private final BroadcastReceiver mResultReceiver = new BroadcastReceiver() {
         @Override
         public void onReceive(Context context, Intent intent) {
-            if (intent.getAction().equals(Intent.ACTION_DEVICE_STORAGE_FULL)) {
-                mStorageAvailable = false;
-                mCi.reportSmsMemoryStatus(false, obtainMessage(EVENT_REPORT_MEMORY_STATUS_DONE));
-            } else if (intent.getAction().equals(Intent.ACTION_DEVICE_STORAGE_NOT_FULL)) {
-                mStorageAvailable = true;
-                mCi.reportSmsMemoryStatus(true, obtainMessage(EVENT_REPORT_MEMORY_STATUS_DONE));
+            final String action = intent.getAction();
+            if (Intent.ACTION_DEVICE_STORAGE_FULL.equals(action)
+                    || Intent.ACTION_DEVICE_STORAGE_NOT_FULL.equals(action)) {
+                mStorageAvailable =
+                        Intent.ACTION_DEVICE_STORAGE_FULL.equals(action) ? false : true;
+                sendMessage(obtainMessage(EVENT_REPORT_MEMORY_STATUS));
             }
         }
     };
diff --git a/src/java/com/android/internal/telephony/SubscriptionController.java b/src/java/com/android/internal/telephony/SubscriptionController.java
index ab61f72..7afd5d2 100644
--- a/src/java/com/android/internal/telephony/SubscriptionController.java
+++ b/src/java/com/android/internal/telephony/SubscriptionController.java
@@ -176,15 +176,10 @@
 
     private AppOpsManager mAppOps;
 
-    // Allows test mocks to avoid SELinux failures on invalidate calls.
-    private static boolean sCachingEnabled = true;
-
     // Each slot can have multiple subs.
     private static class WatchedSlotIndexToSubIds {
-        private Map<Integer, ArrayList<Integer>> mSlotIndexToSubIds = new ConcurrentHashMap<>();
-
-        WatchedSlotIndexToSubIds() {
-        }
+        private final Map<Integer, ArrayList<Integer>> mSlotIndexToSubIds =
+                new ConcurrentHashMap<>();
 
         public void clear() {
             mSlotIndexToSubIds.clear();
@@ -203,7 +198,7 @@
                 return null;
             }
 
-            return new ArrayList<Integer>(subIdList);
+            return new ArrayList<>(subIdList);
         }
 
         public void put(int slotIndex, ArrayList<Integer> value) {
@@ -285,9 +280,9 @@
         }
     }
 
-    private static WatchedSlotIndexToSubIds sSlotIndexToSubIds = new WatchedSlotIndexToSubIds();
+    private final WatchedSlotIndexToSubIds mSlotIndexToSubIds = new WatchedSlotIndexToSubIds();
 
-    protected static WatchedInt sDefaultFallbackSubId =
+    private final WatchedInt mDefaultFallbackSubId =
             new WatchedInt(SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
         @Override
         public void set(int newValue) {
@@ -628,7 +623,6 @@
                     + " publicCardId:" + publicCardId
                     + " isOpportunistic:" + isOpportunistic + " groupUUID:" + groupUUID
                     + " profileClass:" + profileClass + " subscriptionType: " + subType
-                    + " carrierConfigAccessRules:" + carrierConfigAccessRules
                     + " areUiccApplicationsEnabled: " + areUiccApplicationsEnabled
                     + " usageSetting: " + usageSetting);
         }
@@ -1492,7 +1486,7 @@
                             int defaultSubId = getDefaultSubId();
                             if (DBG) {
                                 logdl("[addSubInfoRecord]"
-                                        + " sSlotIndexToSubIds.size=" + sSlotIndexToSubIds.size()
+                                        + " mSlotIndexToSubIds.size=" + mSlotIndexToSubIds.size()
                                         + " slotIndex=" + slotIndex + " subId=" + subId
                                         + " defaultSubId=" + defaultSubId
                                         + " simCount=" + subIdCountMax);
@@ -1501,7 +1495,9 @@
                             // Set the default sub if not set or if single sim device
                             if (!isSubscriptionForRemoteSim(subscriptionType)) {
                                 if (!SubscriptionManager.isValidSubscriptionId(defaultSubId)
-                                        || subIdCountMax == 1) {
+                                        || subIdCountMax == 1
+                                        || mDefaultFallbackSubId.get() ==
+                                        SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
                                     logdl("setting default fallback subid to " + subId);
                                     setDefaultFallbackSubId(subId, subscriptionType);
                                 }
@@ -1572,7 +1568,7 @@
                     if (DBG) logdl("[addSubInfoRecord] sim name = " + nameToSet);
                 }
 
-                if (DBG) logdl("[addSubInfoRecord]- info size=" + sSlotIndexToSubIds.size());
+                if (DBG) logdl("[addSubInfoRecord]- info size=" + mSlotIndexToSubIds.size());
             }
 
         } finally {
@@ -1676,7 +1672,7 @@
                 return -1;
             }
             refreshCachedActiveSubscriptionInfoList();
-            result = sSlotIndexToSubIds.removeFromSubIdList(slotIndex, subId);
+            result = mSlotIndexToSubIds.removeFromSubIdList(slotIndex, subId);
             if (result == NO_ENTRY_FOR_SLOT_INDEX) {
                 loge("sSlotIndexToSubIds has no entry for slotIndex = " + slotIndex);
             } else if (result == SUB_ID_NOT_IN_SLOT) {
@@ -1720,7 +1716,26 @@
         // Refresh the Cache of Active Subscription Info List
         refreshCachedActiveSubscriptionInfoList();
 
-        sSlotIndexToSubIds.remove(slotIndex);
+        boolean isFallBackRefreshRequired = false;
+        if (mDefaultFallbackSubId.get() > SubscriptionManager.INVALID_SUBSCRIPTION_ID &&
+                mSlotIndexToSubIds.getCopy(slotIndex) != null &&
+                mSlotIndexToSubIds.getCopy(slotIndex).contains(mDefaultFallbackSubId.get())) {
+            isFallBackRefreshRequired = true;
+        }
+        mSlotIndexToSubIds.remove(slotIndex);
+        // set mDefaultFallbackSubId to invalid in case mSlotIndexToSubIds do not have any entries
+        if (mSlotIndexToSubIds.size() ==0 ) {
+            mDefaultFallbackSubId.set(SubscriptionManager.INVALID_SUBSCRIPTION_ID);
+        } else if (isFallBackRefreshRequired) {
+            // set mDefaultFallbackSubId to valid subId from mSlotIndexToSubIds
+            for (int index = 0; index < getActiveSubIdArrayList().size(); index ++) {
+                int subId = getActiveSubIdArrayList().get(index);
+                if (subId > SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
+                    mDefaultFallbackSubId.set(subId);
+                    break;
+                }
+            }
+        }
     }
 
     /**
@@ -2607,14 +2622,14 @@
             return SubscriptionManager.INVALID_SIM_SLOT_INDEX;
         }
 
-        int size = sSlotIndexToSubIds.size();
+        int size = mSlotIndexToSubIds.size();
 
         if (size == 0) {
             if (DBG) logd("[getSlotIndex]- size == 0, return SIM_NOT_INSERTED instead");
             return SubscriptionManager.SIM_NOT_INSERTED;
         }
 
-        for (Entry<Integer, ArrayList<Integer>> entry : sSlotIndexToSubIds.entrySet()) {
+        for (Entry<Integer, ArrayList<Integer>> entry : mSlotIndexToSubIds.entrySet()) {
             int sim = entry.getKey();
             ArrayList<Integer> subs = entry.getValue();
 
@@ -2657,7 +2672,7 @@
         }
 
         // Check if we've got any SubscriptionInfo records using slotIndexToSubId as a surrogate.
-        int size = sSlotIndexToSubIds.size();
+        int size = mSlotIndexToSubIds.size();
         if (size == 0) {
             if (VDBG) {
                 logd("[getSubId]- sSlotIndexToSubIds.size == 0, return null slotIndex="
@@ -2667,13 +2682,13 @@
         }
 
         // Convert ArrayList to array
-        ArrayList<Integer> subIds = sSlotIndexToSubIds.getCopy(slotIndex);
+        ArrayList<Integer> subIds = mSlotIndexToSubIds.getCopy(slotIndex);
         if (subIds != null && subIds.size() > 0) {
             int[] subIdArr = new int[subIds.size()];
             for (int i = 0; i < subIds.size(); i++) {
                 subIdArr[i] = subIds.get(i);
             }
-            if (VDBG) logd("[getSubId]- subIdArr=" + subIdArr);
+            if (VDBG) logd("[getSubId]- subIdArr=" + Arrays.toString(subIdArr));
             return subIdArr;
         } else {
             if (DBG) logd("[getSubId]- numSubIds == 0, return null slotIndex=" + slotIndex);
@@ -2700,7 +2715,7 @@
             return SubscriptionManager.INVALID_PHONE_INDEX;
         }
 
-        int size = sSlotIndexToSubIds.size();
+        int size = mSlotIndexToSubIds.size();
         if (size == 0) {
             phoneId = mDefaultPhoneId;
             if (VDBG) logdl("[getPhoneId]- no sims, returning default phoneId=" + phoneId);
@@ -2708,7 +2723,7 @@
         }
 
         // FIXME: Assumes phoneId == slotIndex
-        for (Entry<Integer, ArrayList<Integer>> entry: sSlotIndexToSubIds.entrySet()) {
+        for (Entry<Integer, ArrayList<Integer>> entry: mSlotIndexToSubIds.entrySet()) {
             int sim = entry.getKey();
             ArrayList<Integer> subs = entry.getValue();
 
@@ -2736,14 +2751,14 @@
         // Now that all security checks passes, perform the operation as ourselves.
         final long identity = Binder.clearCallingIdentity();
         try {
-            int size = sSlotIndexToSubIds.size();
+            int size = mSlotIndexToSubIds.size();
 
             if (size == 0) {
                 if (DBG) logdl("[clearSubInfo]- no simInfo size=" + size);
                 return 0;
             }
 
-            sSlotIndexToSubIds.clear();
+            mSlotIndexToSubIds.clear();
             if (DBG) logdl("[clearSubInfo]- clear size=" + size);
             return size;
         } finally {
@@ -2794,7 +2809,7 @@
             if (VDBG) logdl("[getDefaultSubId] NOT VoiceCapable subId=" + subId);
         }
         if (!isActiveSubId(subId)) {
-            subId = sDefaultFallbackSubId.get();
+            subId = mDefaultFallbackSubId.get();
             if (VDBG) logdl("[getDefaultSubId] NOT active use fall back subId=" + subId);
         }
         if (VDBG) logv("[getDefaultSubId]- value = " + subId);
@@ -2987,7 +3002,7 @@
         }
         int previousDefaultSub = getDefaultSubId();
         if (isSubscriptionForRemoteSim(subscriptionType)) {
-            sDefaultFallbackSubId.set(subId);
+            mDefaultFallbackSubId.set(subId);
             return;
         }
         if (SubscriptionManager.isValidSubscriptionId(subId)) {
@@ -2995,7 +3010,7 @@
             if (phoneId >= 0 && (phoneId < mTelephonyManager.getPhoneCount()
                     || mTelephonyManager.getSimCount() == 1)) {
                 if (DBG) logdl("[setDefaultFallbackSubId] set sDefaultFallbackSubId=" + subId);
-                sDefaultFallbackSubId.set(subId);
+                mDefaultFallbackSubId.set(subId);
                 // Update MCC MNC device configuration information
                 String defaultMccMnc = mTelephonyManager.getSimOperatorNumericForPhone(phoneId);
                 MccTable.updateMccMncConfiguration(mContext, defaultMccMnc);
@@ -3095,7 +3110,7 @@
     private synchronized ArrayList<Integer> getActiveSubIdArrayList() {
         // Clone the sub id list so it can't change out from under us while iterating
         List<Entry<Integer, ArrayList<Integer>>> simInfoList =
-                new ArrayList<>(sSlotIndexToSubIds.entrySet());
+                new ArrayList<>(mSlotIndexToSubIds.entrySet());
 
         // Put the set of sub ids in slot index order
         Collections.sort(simInfoList, (x, y) -> x.getKey().compareTo(y.getKey()));
@@ -3425,7 +3440,7 @@
                     .from(mContext).getDefaultSmsPhoneId());
             pw.flush();
 
-            for (Entry<Integer, ArrayList<Integer>> entry : sSlotIndexToSubIds.entrySet()) {
+            for (Entry<Integer, ArrayList<Integer>> entry : mSlotIndexToSubIds.entrySet()) {
                 pw.println(" sSlotIndexToSubId[" + entry.getKey() + "]: subIds=" + entry);
             }
             pw.flush();
@@ -3659,7 +3674,7 @@
     @Override
     public ParcelUuid createSubscriptionGroup(int[] subIdList, String callingPackage) {
         if (subIdList == null || subIdList.length == 0) {
-            throw new IllegalArgumentException("Invalid subIdList " + subIdList);
+            throw new IllegalArgumentException("Invalid subIdList " + Arrays.toString(subIdList));
         }
 
         // Makes sure calling package matches caller UID.
@@ -4440,10 +4455,10 @@
     }
 
     private synchronized boolean addToSubIdList(int slotIndex, int subId, int subscriptionType) {
-        ArrayList<Integer> subIdsList = sSlotIndexToSubIds.getCopy(slotIndex);
+        ArrayList<Integer> subIdsList = mSlotIndexToSubIds.getCopy(slotIndex);
         if (subIdsList == null) {
             subIdsList = new ArrayList<>();
-            sSlotIndexToSubIds.put(slotIndex, subIdsList);
+            mSlotIndexToSubIds.put(slotIndex, subIdsList);
         }
 
         // add the given subId unless it already exists
@@ -4453,20 +4468,20 @@
         }
         if (isSubscriptionForRemoteSim(subscriptionType)) {
             // For Remote SIM subscriptions, a slot can have multiple subscriptions.
-            sSlotIndexToSubIds.addToSubIdList(slotIndex, subId);
+            mSlotIndexToSubIds.addToSubIdList(slotIndex, subId);
         } else {
             // for all other types of subscriptions, a slot can have only one subscription at a time
-            sSlotIndexToSubIds.clearSubIdList(slotIndex);
-            sSlotIndexToSubIds.addToSubIdList(slotIndex, subId);
+            mSlotIndexToSubIds.clearSubIdList(slotIndex);
+            mSlotIndexToSubIds.addToSubIdList(slotIndex, subId);
         }
 
 
         // Remove the slot from sSlotIndexToSubIds if it has the same sub id with the added slot
-        for (Entry<Integer, ArrayList<Integer>> entry : sSlotIndexToSubIds.entrySet()) {
+        for (Entry<Integer, ArrayList<Integer>> entry : mSlotIndexToSubIds.entrySet()) {
             if (entry.getKey() != slotIndex && entry.getValue() != null
                     && entry.getValue().contains(subId)) {
                 logdl("addToSubIdList - remove " + entry.getKey());
-                sSlotIndexToSubIds.remove(entry.getKey());
+                mSlotIndexToSubIds.remove(entry.getKey());
             }
         }
 
@@ -4484,17 +4499,7 @@
      */
     @VisibleForTesting(visibility = VisibleForTesting.Visibility.PRIVATE)
     public Map<Integer, ArrayList<Integer>> getSlotIndexToSubIdsMap() {
-        return sSlotIndexToSubIds.getMap();
-    }
-
-    /**
-     * This is only for testing
-     * @hide
-     */
-    @VisibleForTesting(visibility = VisibleForTesting.Visibility.PRIVATE)
-    public void resetStaticMembers() {
-        sDefaultFallbackSubId.set(SubscriptionManager.INVALID_SUBSCRIPTION_ID);
-        mDefaultPhoneId = SubscriptionManager.DEFAULT_PHONE_INDEX;
+        return mSlotIndexToSubIds.getMap();
     }
 
     private void notifyOpportunisticSubscriptionInfoChanged() {
@@ -4506,11 +4511,11 @@
     }
 
     private void refreshCachedOpportunisticSubscriptionInfoList() {
-        List<SubscriptionInfo> subList = getSubInfo(
-                SubscriptionManager.IS_OPPORTUNISTIC + "=1 AND ("
-                        + SubscriptionManager.SIM_SLOT_INDEX + ">=0 OR "
-                        + SubscriptionManager.IS_EMBEDDED + "=1)", null);
         synchronized (mSubInfoListLock) {
+            List<SubscriptionInfo> subList = getSubInfo(
+                    SubscriptionManager.IS_OPPORTUNISTIC + "=1 AND ("
+                            + SubscriptionManager.SIM_SLOT_INDEX + ">=0 OR "
+                            + SubscriptionManager.IS_EMBEDDED + "=1)", null);
             List<SubscriptionInfo> oldOpptCachedList = mCacheOpportunisticSubInfoList;
 
             if (subList != null) {
@@ -4786,77 +4791,36 @@
      */
     private void setGlobalSetting(String name, int value) {
         Settings.Global.putInt(mContext.getContentResolver(), name, value);
-        if (name == Settings.Global.MULTI_SIM_DATA_CALL_SUBSCRIPTION) {
+        if (TextUtils.equals(name, Settings.Global.MULTI_SIM_DATA_CALL_SUBSCRIPTION)) {
             invalidateDefaultDataSubIdCaches();
             invalidateActiveDataSubIdCaches();
             invalidateDefaultSubIdCaches();
             invalidateSlotIndexCaches();
-        } else if (name == Settings.Global.MULTI_SIM_VOICE_CALL_SUBSCRIPTION) {
+        } else if (TextUtils.equals(name, Settings.Global.MULTI_SIM_VOICE_CALL_SUBSCRIPTION)) {
             invalidateDefaultSubIdCaches();
             invalidateSlotIndexCaches();
-        } else if (name == Settings.Global.MULTI_SIM_SMS_SUBSCRIPTION) {
+        } else if (TextUtils.equals(name, Settings.Global.MULTI_SIM_SMS_SUBSCRIPTION)) {
             invalidateDefaultSmsSubIdCaches();
         }
     }
 
-    /**
-     * @hide
-     */
     private static void invalidateDefaultSubIdCaches() {
-        if (sCachingEnabled) {
-            SubscriptionManager.invalidateDefaultSubIdCaches();
-        }
+        SubscriptionManager.invalidateDefaultSubIdCaches();
     }
 
-    /**
-     * @hide
-     */
     private static void invalidateDefaultDataSubIdCaches() {
-        if (sCachingEnabled) {
-            SubscriptionManager.invalidateDefaultDataSubIdCaches();
-        }
+        SubscriptionManager.invalidateDefaultDataSubIdCaches();
     }
 
-    /**
-     * @hide
-     */
     private static void invalidateDefaultSmsSubIdCaches() {
-        if (sCachingEnabled) {
-            SubscriptionManager.invalidateDefaultSmsSubIdCaches();
-        }
+        SubscriptionManager.invalidateDefaultSmsSubIdCaches();
     }
 
-    /**
-     * @hide
-     */
-    public static void invalidateActiveDataSubIdCaches() {
-        if (sCachingEnabled) {
-            SubscriptionManager.invalidateActiveDataSubIdCaches();
-        }
+    private static void invalidateActiveDataSubIdCaches() {
+        SubscriptionManager.invalidateActiveDataSubIdCaches();
     }
 
-    /**
-     * @hide
-     */
-    protected static void invalidateSlotIndexCaches() {
-        if (sCachingEnabled) {
-            SubscriptionManager.invalidateSlotIndexCaches();
-        }
-    }
-
-    /**
-     * @hide
-     */
-    @VisibleForTesting
-    public static void disableCaching() {
-        sCachingEnabled = false;
-    }
-
-    /**
-     * @hide
-     */
-    @VisibleForTesting
-    public static void enableCaching() {
-        sCachingEnabled = true;
+    private static void invalidateSlotIndexCaches() {
+        SubscriptionManager.invalidateSlotIndexCaches();
     }
 }
diff --git a/src/java/com/android/internal/telephony/SubscriptionInfoUpdater.java b/src/java/com/android/internal/telephony/SubscriptionInfoUpdater.java
index 3ab229a..60f9a62 100644
--- a/src/java/com/android/internal/telephony/SubscriptionInfoUpdater.java
+++ b/src/java/com/android/internal/telephony/SubscriptionInfoUpdater.java
@@ -1194,7 +1194,8 @@
             loge("Cannot manage subId=" + currentSubId + ", carrierPackage=" + configPackageName);
         } else {
             boolean isOpportunistic = config.getBoolean(
-                    CarrierConfigManager.KEY_IS_OPPORTUNISTIC_SUBSCRIPTION_BOOL, false);
+                    CarrierConfigManager.KEY_IS_OPPORTUNISTIC_SUBSCRIPTION_BOOL,
+                    currentSubInfo.isOpportunistic());
             if (currentSubInfo.isOpportunistic() != isOpportunistic) {
                 if (DBG) logd("Set SubId=" + currentSubId + " isOpportunistic=" + isOpportunistic);
                 cv.put(SubscriptionManager.IS_OPPORTUNISTIC, isOpportunistic ? "1" : "0");
diff --git a/src/java/com/android/internal/telephony/data/DataNetwork.java b/src/java/com/android/internal/telephony/data/DataNetwork.java
index b4d49f7..7616b93 100644
--- a/src/java/com/android/internal/telephony/data/DataNetwork.java
+++ b/src/java/com/android/internal/telephony/data/DataNetwork.java
@@ -643,6 +643,11 @@
      */
     private @TransportType int mTransport;
 
+    /**
+     * The last known data network type.
+     */
+    private @NetworkType int mLastKnownDataNetworkType;
+
     /** The reason that why setting up this data network is allowed. */
     private @NonNull DataAllowedReason mDataAllowedReason;
 
@@ -887,6 +892,7 @@
             mTrafficDescriptors.add(dataProfile.getTrafficDescriptor());
         }
         mTransport = transport;
+        mLastKnownDataNetworkType = getDataNetworkType();
         mDataAllowedReason = dataAllowedReason;
         dataProfile.setLastSetupTimestamp(SystemClock.elapsedRealtime());
         mAttachedNetworkRequestList.addAll(networkRequestList);
@@ -1077,7 +1083,11 @@
                     onCarrierConfigUpdated();
                     break;
                 case EVENT_SERVICE_STATE_CHANGED: {
-                    mDataCallSessionStats.onDrsOrRatChanged(getDataNetworkType());
+                    int networkType = getDataNetworkType();
+                    mDataCallSessionStats.onDrsOrRatChanged(networkType);
+                    if (networkType != TelephonyManager.NETWORK_TYPE_UNKNOWN) {
+                        mLastKnownDataNetworkType = networkType;
+                    }
                     updateSuspendState();
                     updateNetworkCapabilities();
                     break;
@@ -3292,8 +3302,14 @@
     }
 
     /**
-     * @return The PCO data map of the network. The key is the PCO id, the value is the PCO data.
-     * An empty map if PCO data is not available (or when the network is on IWLAN).
+     * @return The last known data network type of the data network.
+     */
+    public @NetworkType int getLastKnownDataNetworkType() {
+        return mLastKnownDataNetworkType;
+    }
+
+    /**
+     * @return The PCO data received from the network.
      */
     public @NonNull Map<Integer, PcoData> getPcoData() {
         if (mTransport == AccessNetworkConstants.TRANSPORT_TYPE_WLAN
@@ -3542,6 +3558,8 @@
         pw.increaseIndent();
         pw.println("mSubId=" + mSubId);
         pw.println("mTransport=" + AccessNetworkConstants.transportTypeToString(mTransport));
+        pw.println("mLastKnownDataNetworkType=" + TelephonyManager
+                .getNetworkTypeName(mLastKnownDataNetworkType));
         pw.println("WWAN cid=" + mCid.get(AccessNetworkConstants.TRANSPORT_TYPE_WWAN));
         pw.println("WLAN cid=" + mCid.get(AccessNetworkConstants.TRANSPORT_TYPE_WLAN));
         pw.println("mNetworkScore=" + mNetworkScore);
diff --git a/src/java/com/android/internal/telephony/data/DataNetworkController.java b/src/java/com/android/internal/telephony/data/DataNetworkController.java
index bf3bab1..8f8da63 100644
--- a/src/java/com/android/internal/telephony/data/DataNetworkController.java
+++ b/src/java/com/android/internal/telephony/data/DataNetworkController.java
@@ -1125,8 +1125,8 @@
                 log("Subscription plans changed: " + Arrays.toString(plans));
                 mSubscriptionPlans.clear();
                 mSubscriptionPlans.addAll(Arrays.asList(plans));
-                mDataNetworkControllerCallbacks.forEach(callback -> callback.invokeFromExecutor(
-                        () -> callback.onSubscriptionPlanOverride()));
+                mDataNetworkControllerCallbacks.forEach(cb -> cb.invokeFromExecutor(
+                        () -> cb.onSubscriptionPlanOverride()));
                 break;
             case EVENT_SUBSCRIPTION_OVERRIDE:
                 int overrideMask = msg.arg1;
@@ -1145,8 +1145,8 @@
                             mUnmeteredOverrideNetworkTypes.remove(networkType);
                         }
                     }
-                    mDataNetworkControllerCallbacks.forEach(callback -> callback.invokeFromExecutor(
-                            () -> callback.onSubscriptionPlanOverride()));
+                    mDataNetworkControllerCallbacks.forEach(cb -> cb.invokeFromExecutor(
+                            () -> cb.onSubscriptionPlanOverride()));
                 } else if (overrideMask == NetworkPolicyManager.SUBSCRIPTION_OVERRIDE_CONGESTED) {
                     log("Congested subscription override: override=" + override
                             + ", networkTypes=" + Arrays.stream(networkTypes)
@@ -1159,8 +1159,8 @@
                             mCongestedOverrideNetworkTypes.remove(networkType);
                         }
                     }
-                    mDataNetworkControllerCallbacks.forEach(callback -> callback.invokeFromExecutor(
-                            () -> callback.onSubscriptionPlanOverride()));
+                    mDataNetworkControllerCallbacks.forEach(cb -> cb.invokeFromExecutor(
+                            () -> cb.onSubscriptionPlanOverride()));
                 } else {
                     loge("Unknown override mask: " + overrideMask);
                 }
@@ -1319,7 +1319,7 @@
         if (nriRegState == NetworkRegistrationInfo.REGISTRATION_STATE_HOME
                 || nriRegState == NetworkRegistrationInfo.REGISTRATION_STATE_ROAMING) return true;
 
-        // If data is OOS on the non-DDS,
+        // If data is OOS as this device slot is not modem preferred(i.e. not active for internet),
         // attempt to attach PS on 2G/3G if CS connection is available.
         return ss.getVoiceRegState() == ServiceState.STATE_IN_SERVICE
                 && mPhone.getPhoneId() != PhoneSwitcher.getInstance().getPreferredDataPhoneId()
@@ -1576,8 +1576,15 @@
         }
 
         // Check if there is any compatible data profile
+        int networkType = getDataNetworkType(transport);
+        if (networkType == TelephonyManager.NETWORK_TYPE_UNKNOWN
+                && transport == AccessNetworkConstants.TRANSPORT_TYPE_WWAN) {
+            // reach here when data is OOS but serviceStateAllowsPSAttach == true, so we adopt the
+            // voice RAT to select data profile
+            networkType = mServiceState.getVoiceNetworkType();
+        }
         DataProfile dataProfile = mDataProfileManager
-                .getDataProfileForNetworkRequest(networkRequest, getDataNetworkType(transport),
+                .getDataProfileForNetworkRequest(networkRequest, networkType,
                         // If the evaluation is due to environmental changes, then we should ignore
                         // the permanent failure reached earlier.
                         reason.isConditionBased());
@@ -1906,8 +1913,18 @@
         if (mDataConfigManager.isIwlanHandoverPolicyEnabled()) {
             List<HandoverRule> handoverRules = mDataConfigManager.getHandoverRules();
 
+            int sourceNetworkType = getDataNetworkType(dataNetwork.getTransport());
+            if (sourceNetworkType == TelephonyManager.NETWORK_TYPE_UNKNOWN) {
+                // Using the data network type stored in the data network. We
+                // cache the last known network type in data network controller
+                // because data network has much shorter life cycle. It can prevent
+                // the obsolete last known network type cached in data network
+                // type controller.
+                sourceNetworkType = dataNetwork.getLastKnownDataNetworkType();
+            }
             int sourceAccessNetwork = DataUtils.networkTypeToAccessNetworkType(
-                    getDataNetworkType(dataNetwork.getTransport()));
+                    sourceNetworkType);
+
             int targetAccessNetwork = DataUtils.networkTypeToAccessNetworkType(
                     getDataNetworkType(DataUtils.getTargetTransport(dataNetwork.getTransport())));
             NetworkCapabilities capabilities = dataNetwork.getNetworkCapabilities();
diff --git a/src/java/com/android/internal/telephony/data/DataProfileManager.java b/src/java/com/android/internal/telephony/data/DataProfileManager.java
index e8f1922..7976362 100644
--- a/src/java/com/android/internal/telephony/data/DataProfileManager.java
+++ b/src/java/com/android/internal/telephony/data/DataProfileManager.java
@@ -106,6 +106,9 @@
     /** The preferred data profile used for internet. */
     private @Nullable DataProfile mPreferredDataProfile = null;
 
+    /** The last data profile that's successful for internet connection. */
+    private @Nullable DataProfile mLastInternetDataProfile = null;
+
     /** Preferred data profile set id. */
     private int mPreferredDataProfileSetId = Telephony.Carriers.NO_APN_SET_ID;
 
@@ -166,7 +169,12 @@
                     public void onInternetDataNetworkConnected(
                             @NonNull List<DataProfile> dataProfiles) {
                         DataProfileManager.this.onInternetDataNetworkConnected(dataProfiles);
-                    }});
+                    }
+                    @Override
+                    public void onInternetDataNetworkDisconnected() {
+                        DataProfileManager.this.onInternetDataNetworkDisconnected();
+                    }
+                });
         mDataConfigManager.registerCallback(new DataConfigManagerCallback(this::post) {
             @Override
             public void onCarrierConfigChanged() {
@@ -285,9 +293,27 @@
             }
         }
 
+        DataProfile dataProfile;
+
+        if (!profiles.isEmpty()) { // APN database has been read successfully after SIM loaded
+            // Check if any of the profile already supports IMS, if not, add the default one.
+            dataProfile = profiles.stream()
+                    .filter(dp -> dp.canSatisfy(NetworkCapabilities.NET_CAPABILITY_IMS))
+                    .findFirst()
+                    .orElse(null);
+            if (dataProfile == null) {
+                profiles.add(new DataProfile.Builder()
+                        .setApnSetting(buildDefaultApnSetting("DEFAULT IMS", "ims",
+                                ApnSetting.TYPE_IMS))
+                        .setTrafficDescriptor(new TrafficDescriptor("ims", null))
+                        .build());
+                log("Added default IMS data profile.");
+            }
+        }
+
         // Check if any of the profile already supports ENTERPRISE, if not, check if DPC has
         // configured one and retrieve the same.
-        DataProfile dataProfile = profiles.stream()
+        dataProfile = profiles.stream()
                 .filter(dp -> dp.canSatisfy(NetworkCapabilities.NET_CAPABILITY_ENTERPRISE))
                 .findFirst()
                 .orElse(null);
@@ -299,20 +325,6 @@
             }
         }
 
-        // Check if any of the profile already supports IMS, if not, add the default one.
-        dataProfile = profiles.stream()
-                .filter(dp -> dp.canSatisfy(NetworkCapabilities.NET_CAPABILITY_IMS))
-                .findFirst()
-                .orElse(null);
-        if (dataProfile == null) {
-            profiles.add(new DataProfile.Builder()
-                    .setApnSetting(buildDefaultApnSetting("DEFAULT IMS", "ims",
-                            ApnSetting.TYPE_IMS))
-                    .setTrafficDescriptor(new TrafficDescriptor("ims", null))
-                    .build());
-            log("Added default IMS data profile.");
-        }
-
         // Check if any of the profile already supports EIMS, if not, add the default one.
         dataProfile = profiles.stream()
                 .filter(dp -> dp.canSatisfy(NetworkCapabilities.NET_CAPABILITY_EIMS))
@@ -410,12 +422,20 @@
         DataProfile dataProfile = dataProfiles.stream()
                 .max(Comparator.comparingLong(DataProfile::getLastSetupTimestamp).reversed())
                 .orElse(null);
+        mLastInternetDataProfile = dataProfile;
         // Save the preferred data profile into database.
         setPreferredDataProfile(dataProfile);
         updateDataProfiles(ONLY_UPDATE_IA_IF_CHANGED);
     }
 
     /**
+     * Called when internet data is disconnected.
+     */
+    private void onInternetDataNetworkDisconnected() {
+        mLastInternetDataProfile = null;
+    }
+
+    /**
      * Get the preferred data profile for internet data.
      *
      * @return The preferred data profile.
@@ -498,12 +518,12 @@
                     setPreferredDataProfile(preferredDataProfile);
                 } else {
                     preferredDataProfile = mAllDataProfiles.stream()
-                            .filter(dp -> areDataProfilesSharingApn(dp, mPreferredDataProfile))
+                            .filter(dp -> areDataProfilesSharingApn(dp, mLastInternetDataProfile))
                             .findFirst()
                             .orElse(null);
                     if (preferredDataProfile != null) {
                         log("updatePreferredDataProfile: preferredDB is empty and no carrier "
-                                + "default configured, setting preferred to be prev preferred DP.");
+                                + "default configured, setting preferred to be prev internet DP.");
                         setPreferredDataProfile(preferredDataProfile);
                     }
                 }
@@ -980,14 +1000,13 @@
             return true;
         }
 
-        // Only check the APN from the profile is compatible or not.
+        // Check the APN from the profile is compatible and matches preferred data profile set id.
         return mAllDataProfiles.stream()
                 .filter(dp -> dp.getApnSetting() != null
                         && (dp.getApnSetting().getApnSetId()
                         == Telephony.Carriers.MATCH_ALL_APN_SET_ID
                         || dp.getApnSetting().getApnSetId() == mPreferredDataProfileSetId))
                 .anyMatch(dp -> areDataProfilesSharingApn(dataProfile, dp));
-
     }
 
     /**
diff --git a/src/java/com/android/internal/telephony/data/DataRetryManager.java b/src/java/com/android/internal/telephony/data/DataRetryManager.java
index 0faad2c..0beea1f 100644
--- a/src/java/com/android/internal/telephony/data/DataRetryManager.java
+++ b/src/java/com/android/internal/telephony/data/DataRetryManager.java
@@ -1009,18 +1009,16 @@
         switch (msg.what) {
             case EVENT_DATA_SETUP_RETRY:
                 DataSetupRetryEntry dataSetupRetryEntry = (DataSetupRetryEntry) msg.obj;
-                Objects.requireNonNull(dataSetupRetryEntry);
-                mDataRetryManagerCallbacks.forEach(callback -> callback.invokeFromExecutor(
-                        () -> callback.onDataNetworkSetupRetry(dataSetupRetryEntry)));
+                if (!isRetryCancelled(dataSetupRetryEntry)) {
+                    mDataRetryManagerCallbacks.forEach(callback -> callback.invokeFromExecutor(
+                            () -> callback.onDataNetworkSetupRetry(dataSetupRetryEntry)));
+                }
                 break;
             case EVENT_DATA_HANDOVER_RETRY:
                 DataHandoverRetryEntry dataHandoverRetryEntry = (DataHandoverRetryEntry) msg.obj;
-                Objects.requireNonNull(dataHandoverRetryEntry);
-                if (mDataRetryEntries.contains(dataHandoverRetryEntry)) {
+                if (!isRetryCancelled(dataHandoverRetryEntry)) {
                     mDataRetryManagerCallbacks.forEach(callback -> callback.invokeFromExecutor(
                             () -> callback.onDataNetworkHandoverRetry(dataHandoverRetryEntry)));
-                } else {
-                    log("Handover was cancelled earlier. " + dataHandoverRetryEntry);
                 }
                 break;
             case EVENT_RADIO_ON:
@@ -1054,6 +1052,18 @@
     }
 
     /**
+     * @param retryEntry The retry entry to check.
+     * @return {@code true} if the retry is null or not in RETRY_STATE_NOT_RETRIED state.
+     */
+    private boolean isRetryCancelled(@Nullable DataRetryEntry retryEntry) {
+        if (retryEntry != null && retryEntry.getState() == DataRetryEntry.RETRY_STATE_NOT_RETRIED) {
+            return false;
+        }
+        log("Retry was removed earlier. " + retryEntry);
+        return true;
+    }
+
+    /**
      * Called when carrier config is updated.
      */
     private void onCarrierConfigUpdated() {
@@ -1536,6 +1546,11 @@
         mDataRetryManagerCallbacks.forEach(callback -> callback.invokeFromExecutor(
                 () -> callback.onThrottleStatusChanged(throttleStatusList)));
 
+        if (unthrottledProfile != null) {
+            // cancel pending retries since we will soon schedule an immediate retry
+            cancelRetriesForDataProfile(unthrottledProfile, transport);
+        }
+
         logl("onDataProfileUnthrottled: Removing the following throttling entries. "
                 + dataUnthrottlingEntries);
         if (retry) {
@@ -1563,6 +1578,34 @@
     }
 
     /**
+     * Cancel pending retries that uses the specified data profile, with specified target transport.
+     *
+     * @param dataProfile The data profile to cancel.
+     * @param transport The target {@link TransportType} on which the retry to cancel.
+     */
+    private void cancelRetriesForDataProfile(@NonNull DataProfile dataProfile,
+            @TransportType int transport) {
+        logl("cancelRetriesForDataProfile: Canceling pending retries for " + dataProfile);
+        mDataRetryEntries.stream()
+                .filter(entry -> {
+                    if (entry.getState() == DataRetryEntry.RETRY_STATE_NOT_RETRIED) {
+                        if (entry instanceof DataSetupRetryEntry) {
+                            DataSetupRetryEntry retryEntry = (DataSetupRetryEntry) entry;
+                            return dataProfile.equals(retryEntry.dataProfile)
+                                    && transport == retryEntry.transport;
+                        } else if (entry instanceof DataHandoverRetryEntry) {
+                            DataHandoverRetryEntry retryEntry = (DataHandoverRetryEntry) entry;
+                            return dataProfile.equals(retryEntry.dataNetwork.getDataProfile());
+                        }
+                    }
+                    return false;
+                })
+                .forEach(entry -> entry.setState(DataRetryEntry.RETRY_STATE_CANCELLED));
+    }
+
+
+
+    /**
      * Check if there is any similar network request scheduled to retry. The definition of similar
      * is that network requests have same APN capability and on the same transport.
      *
@@ -1646,14 +1689,18 @@
      * @param dataNetwork The data network that was originally scheduled for handover retry.
      */
     private void onCancelPendingHandoverRetry(@NonNull DataNetwork dataNetwork) {
-        mDataRetryEntries.removeIf(entry -> entry instanceof DataHandoverRetryEntry
-                && ((DataHandoverRetryEntry) entry).dataNetwork == dataNetwork);
+        mDataRetryEntries.stream()
+                .filter(entry -> entry instanceof DataHandoverRetryEntry
+                        && ((DataHandoverRetryEntry) entry).dataNetwork == dataNetwork
+                        && entry.getState() == DataRetryEntry.RETRY_STATE_NOT_RETRIED)
+                .forEach(entry -> entry.setState(DataRetryEntry.RETRY_STATE_CANCELLED));
         mDataThrottlingEntries.removeIf(entry -> entry.dataNetwork == dataNetwork);
     }
 
     /**
      * Check if there is any data handover retry scheduled.
      *
+     *
      * @param dataNetwork The network network to retry handover.
      * @return {@code true} if there is retry scheduled for this network capability.
      */
diff --git a/src/java/com/android/internal/telephony/data/LinkBandwidthEstimator.java b/src/java/com/android/internal/telephony/data/LinkBandwidthEstimator.java
index c225b3f..efed84a 100644
--- a/src/java/com/android/internal/telephony/data/LinkBandwidthEstimator.java
+++ b/src/java/com/android/internal/telephony/data/LinkBandwidthEstimator.java
@@ -1175,8 +1175,7 @@
             StringBuilder sb = new StringBuilder();
             sb.append("Plmn").append(mPlmn)
                     .append("Rat").append(mDataRat)
-                    .append("Tac").append(mTac)
-                    .toString();
+                    .append("Tac").append(mTac);
             return sb.toString();
         }
     }
diff --git a/src/java/com/android/internal/telephony/data/PhoneSwitcher.java b/src/java/com/android/internal/telephony/data/PhoneSwitcher.java
index cc5f447..5bd4de9 100644
--- a/src/java/com/android/internal/telephony/data/PhoneSwitcher.java
+++ b/src/java/com/android/internal/telephony/data/PhoneSwitcher.java
@@ -249,7 +249,7 @@
         @Override
         public void set(int newValue) {
             super.set(newValue);
-            SubscriptionController.invalidateActiveDataSubIdCaches();
+            SubscriptionManager.invalidateActiveDataSubIdCaches();
         }
     };
 
@@ -395,7 +395,7 @@
     public static PhoneSwitcher make(int maxDataAttachModemCount, Context context, Looper looper) {
         if (sPhoneSwitcher == null) {
             sPhoneSwitcher = new PhoneSwitcher(maxDataAttachModemCount, context, looper);
-            SubscriptionController.invalidateActiveDataSubIdCaches();
+            SubscriptionManager.invalidateActiveDataSubIdCaches();
         }
 
         return sPhoneSwitcher;
diff --git a/src/java/com/android/internal/telephony/data/QosCallbackTracker.java b/src/java/com/android/internal/telephony/data/QosCallbackTracker.java
index b7cecbd..bde24df 100644
--- a/src/java/com/android/internal/telephony/data/QosCallbackTracker.java
+++ b/src/java/com/android/internal/telephony/data/QosCallbackTracker.java
@@ -37,6 +37,7 @@
 
 import java.net.InetAddress;
 import java.net.InetSocketAddress;
+import java.net.UnknownHostException;
 import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.HashSet;
@@ -280,41 +281,61 @@
 
     private boolean matchesByLocalAddress(final @NonNull QosBearerFilter sessionFilter,
             final @NonNull IFilter filter) {
-        if (sessionFilter.getLocalPortRange() == null) return false;
-        for (final LinkAddress qosAddress : sessionFilter.getLocalAddresses()) {
-            return filter.matchesLocalAddress(qosAddress.getAddress(),
-                    sessionFilter.getLocalPortRange().getStart(),
-                    sessionFilter.getLocalPortRange().getEnd());
+        int portStart;
+        int portEnd;
+        if (sessionFilter.getLocalPortRange() == null) {
+            portStart = QosBearerFilter.QOS_MIN_PORT;
+            portEnd = QosBearerFilter.QOS_MAX_PORT;
+        } else if (sessionFilter.getLocalPortRange().isValid()) {
+            portStart = sessionFilter.getLocalPortRange().getStart();
+            portEnd = sessionFilter.getLocalPortRange().getEnd();
+        } else {
+            return false;
+        }
+        if (sessionFilter.getLocalAddresses().isEmpty()) {
+            InetAddress anyAddress;
+            try {
+                anyAddress = InetAddress.getByAddress(new byte[] {0, 0, 0, 0});
+            } catch (UnknownHostException e) {
+                return false;
+            }
+            return filter.matchesLocalAddress(anyAddress, portStart, portEnd);
+        } else {
+            for (final LinkAddress qosAddress : sessionFilter.getLocalAddresses()) {
+                return filter.matchesLocalAddress(qosAddress.getAddress(), portStart, portEnd);
+            }
         }
         return false;
     }
 
     private boolean matchesByRemoteAddress(@NonNull QosBearerFilter sessionFilter,
             final @NonNull IFilter filter) {
-        if (sessionFilter.getRemotePortRange() == null) return false;
-        for (final LinkAddress qosAddress : sessionFilter.getRemoteAddresses()) {
-            return filter.matchesRemoteAddress(qosAddress.getAddress(),
-                    sessionFilter.getRemotePortRange().getStart(),
-                    sessionFilter.getRemotePortRange().getEnd());
+        int portStart;
+        int portEnd;
+        boolean result = false;
+        if (sessionFilter.getRemotePortRange() == null) {
+            portStart = QosBearerFilter.QOS_MIN_PORT;
+            portEnd = QosBearerFilter.QOS_MAX_PORT;
+        } else if (sessionFilter.getRemotePortRange().isValid()) {
+            portStart = sessionFilter.getRemotePortRange().getStart();
+            portEnd = sessionFilter.getRemotePortRange().getEnd();
+        } else {
+            return false;
         }
-        return false;
-    }
-
-    private boolean matchesByRemoteAndLocalAddress(@NonNull QosBearerFilter sessionFilter,
-            final @NonNull IFilter filter) {
-        if (sessionFilter.getLocalPortRange() == null
-                || sessionFilter.getRemotePortRange() == null) return false;
-        for (final LinkAddress remoteAddress : sessionFilter.getRemoteAddresses()) {
-            for (final LinkAddress localAddress : sessionFilter.getLocalAddresses()) {
-                return filter.matchesRemoteAddress(remoteAddress.getAddress(),
-                        sessionFilter.getRemotePortRange().getStart(),
-                        sessionFilter.getRemotePortRange().getEnd())
-                        && filter.matchesLocalAddress(localAddress.getAddress(),
-                              sessionFilter.getLocalPortRange().getStart(),
-                              sessionFilter.getLocalPortRange().getEnd());
+        if (sessionFilter.getRemoteAddresses().isEmpty()) {
+            InetAddress anyAddress;
+            try {
+                anyAddress = InetAddress.getByAddress(new byte[] {0, 0, 0, 0});
+            } catch (UnknownHostException e) {
+                return false;
+            }
+            result = filter.matchesRemoteAddress(anyAddress, portStart, portEnd);
+        } else {
+            for (final LinkAddress qosAddress : sessionFilter.getRemoteAddresses()) {
+                result = filter.matchesRemoteAddress(qosAddress.getAddress(), portStart, portEnd);
             }
         }
-        return false;
+        return result;
     }
 
     private QosBearerFilter getFilterByPrecedence(
@@ -329,27 +350,26 @@
         QosBearerFilter qosFilter = null;
 
         for (final QosBearerFilter sessionFilter : qosBearerSession.getQosBearerFilterList()) {
+            boolean unMatched = false;
+            boolean hasMatchedFilter = false;
             if (!sessionFilter.getLocalAddresses().isEmpty()
-                    && !sessionFilter.getRemoteAddresses().isEmpty()
-                    && sessionFilter.getLocalPortRange() != null
-                    && sessionFilter.getLocalPortRange().isValid()
-                    && sessionFilter.getRemotePortRange() != null
-                    && sessionFilter.getRemotePortRange().isValid()) {
-                if (matchesByRemoteAndLocalAddress(sessionFilter, filter)) {
-                    qosFilter = getFilterByPrecedence(qosFilter, sessionFilter);
+                    || sessionFilter.getLocalPortRange() != null) {
+                if (!matchesByLocalAddress(sessionFilter, filter)) {
+                    unMatched = true;
+                } else {
+                    hasMatchedFilter = true;
                 }
-            } else if (!sessionFilter.getRemoteAddresses().isEmpty()
-                    && sessionFilter.getRemotePortRange() != null
-                    && sessionFilter.getRemotePortRange().isValid()) {
-                if (matchesByRemoteAddress(sessionFilter, filter)) {
-                    qosFilter = getFilterByPrecedence(qosFilter, sessionFilter);
+            }
+            if (!sessionFilter.getRemoteAddresses().isEmpty()
+                    || sessionFilter.getRemotePortRange() != null) {
+                if (!matchesByRemoteAddress(sessionFilter, filter)) {
+                    unMatched = true;
+                } else {
+                    hasMatchedFilter = true;
                 }
-            } else if (!sessionFilter.getLocalAddresses().isEmpty()
-                    && sessionFilter.getLocalPortRange() != null
-                    && sessionFilter.getLocalPortRange().isValid()) {
-                if (matchesByLocalAddress(sessionFilter, filter)) {
-                    qosFilter = getFilterByPrecedence(qosFilter, sessionFilter);
-                }
+            }
+            if (!unMatched && hasMatchedFilter) {
+                qosFilter = getFilterByPrecedence(qosFilter, sessionFilter);
             }
         }
         return qosFilter;
diff --git a/src/java/com/android/internal/telephony/dataconnection/DataConnection.java b/src/java/com/android/internal/telephony/dataconnection/DataConnection.java
index 348908a..255972a 100644
--- a/src/java/com/android/internal/telephony/dataconnection/DataConnection.java
+++ b/src/java/com/android/internal/telephony/dataconnection/DataConnection.java
@@ -2703,6 +2703,12 @@
                     }
                     ApnContext.requestLog(
                             cp.mApnContext, "onSetupConnectionCompleted result=" + result);
+
+                    if (result != SetupResult.SUCCESS) {
+                        releasePduSessionId(() -> DataConnection.this
+                                .setPduSessionId(PDU_SESSION_ID_NOT_SET));
+                    }
+
                     switch (result) {
                         case SUCCESS:
                             // All is well
diff --git a/src/java/com/android/internal/telephony/gsm/SuppServiceNotification.java b/src/java/com/android/internal/telephony/gsm/SuppServiceNotification.java
index 41e76ae..396e94c 100644
--- a/src/java/com/android/internal/telephony/gsm/SuppServiceNotification.java
+++ b/src/java/com/android/internal/telephony/gsm/SuppServiceNotification.java
@@ -18,6 +18,8 @@
 
 import android.telephony.PhoneNumberUtils;
 
+import java.util.Arrays;
+
 /**
  * Represents a Supplementary Service Notification received from the network.
  *
@@ -200,7 +202,7 @@
             + (notificationType == 0 ? " originated " : " terminated ")
             + " code: " + code
             + " index: " + index
-            + " history: " + history
+            + " history: " + Arrays.toString(history)
             + " \""
             + PhoneNumberUtils.stringFromStringAndTOA(number, type) + "\" ";
     }
diff --git a/src/java/com/android/internal/telephony/imsphone/ImsPhoneCallTracker.java b/src/java/com/android/internal/telephony/imsphone/ImsPhoneCallTracker.java
index dc41bb4..82dfc6b 100644
--- a/src/java/com/android/internal/telephony/imsphone/ImsPhoneCallTracker.java
+++ b/src/java/com/android/internal/telephony/imsphone/ImsPhoneCallTracker.java
@@ -2735,6 +2735,9 @@
             mPendingMO.finalize();
             mPendingMO = null;
         }
+        // Ensure aggregate state for this tracker is also updated to reflect the new state.
+        updatePhoneState();
+        mPhone.notifyPreciseCallStateChanged();
     }
 
     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
diff --git a/src/java/com/android/internal/telephony/imsphone/ImsPhoneConnection.java b/src/java/com/android/internal/telephony/imsphone/ImsPhoneConnection.java
index c60a4db..68de4a3 100755
--- a/src/java/com/android/internal/telephony/imsphone/ImsPhoneConnection.java
+++ b/src/java/com/android/internal/telephony/imsphone/ImsPhoneConnection.java
@@ -1166,17 +1166,24 @@
      */
     public void startRtt(android.telecom.Connection.RttTextStream textStream) {
         ImsCall imsCall = getImsCall();
-        if (imsCall != null) {
-            getImsCall().sendRttModifyRequest(true);
-            setCurrentRttTextStream(textStream);
+        if (imsCall == null) {
+            Rlog.w(LOG_TAG, "startRtt failed, imsCall is null");
+            return;
         }
+        imsCall.sendRttModifyRequest(true);
+        setCurrentRttTextStream(textStream);
     }
 
     /**
      * Terminate the current RTT session.
      */
     public void stopRtt() {
-        getImsCall().sendRttModifyRequest(false);
+        ImsCall imsCall = getImsCall();
+        if (imsCall == null) {
+            Rlog.w(LOG_TAG, "stopRtt failed, imsCall is null");
+            return;
+        }
+        imsCall.sendRttModifyRequest(false);
     }
 
     /**
@@ -1188,14 +1195,15 @@
     public void sendRttModifyResponse(android.telecom.Connection.RttTextStream textStream) {
         boolean accept = textStream != null;
         ImsCall imsCall = getImsCall();
-
-        if (imsCall != null) {
-            imsCall.sendRttModifyResponse(accept);
-            if (accept) {
-                setCurrentRttTextStream(textStream);
-            } else {
-                Rlog.e(LOG_TAG, "sendRttModifyResponse: foreground call has no connections");
-            }
+        if (imsCall == null) {
+            Rlog.w(LOG_TAG, "sendRttModifyResponse failed, imsCall is null");
+            return;
+        }
+        imsCall.sendRttModifyResponse(accept);
+        if (accept) {
+            setCurrentRttTextStream(textStream);
+        } else {
+            Rlog.e(LOG_TAG, "sendRttModifyResponse: foreground call has no connections");
         }
     }
 
@@ -1276,6 +1284,8 @@
                     ImsCall imsCall = getImsCall();
                     if (imsCall != null) {
                         imsCall.sendRttMessage(message);
+                    } else {
+                        Rlog.w(LOG_TAG, "createRttTextHandler: imsCall is null");
                     }
                 });
         mRttTextHandler.initialize(mRttTextStream);
diff --git a/src/java/com/android/internal/telephony/metrics/MetricsCollector.java b/src/java/com/android/internal/telephony/metrics/MetricsCollector.java
index 6882899..203e011 100644
--- a/src/java/com/android/internal/telephony/metrics/MetricsCollector.java
+++ b/src/java/com/android/internal/telephony/metrics/MetricsCollector.java
@@ -48,6 +48,7 @@
 import static com.android.internal.telephony.TelephonyStatsLog.UCE_EVENT_STATS;
 import static com.android.internal.telephony.TelephonyStatsLog.VOICE_CALL_RAT_USAGE;
 import static com.android.internal.telephony.TelephonyStatsLog.VOICE_CALL_SESSION;
+import static com.android.internal.telephony.TelephonyStatsLog.VOICE_CALL_SESSION__CALL_DURATION__CALL_DURATION_UNKNOWN;
 
 import android.annotation.Nullable;
 import android.app.StatsManager;
@@ -737,7 +738,8 @@
                 session.bearerAtStart,
                 session.bearerAtEnd,
                 session.direction,
-                session.setupDuration,
+                // deprecated and replaced by setupDurationMillis
+                VOICE_CALL_SESSION__CALL_DURATION__CALL_DURATION_UNKNOWN,
                 session.setupFailed,
                 session.disconnectReasonCode,
                 session.disconnectExtraCode,
diff --git a/src/java/com/android/internal/telephony/metrics/ServiceStateStats.java b/src/java/com/android/internal/telephony/metrics/ServiceStateStats.java
index 42dc55d..dea3142 100644
--- a/src/java/com/android/internal/telephony/metrics/ServiceStateStats.java
+++ b/src/java/com/android/internal/telephony/metrics/ServiceStateStats.java
@@ -193,6 +193,9 @@
             case TelephonyManager.NETWORK_TYPE_LTE_CA:
                 band = AccessNetworkUtils.getOperatingBandForEarfcn(chNumber);
                 break;
+            case TelephonyManager.NETWORK_TYPE_NR:
+                band = AccessNetworkUtils.getOperatingBandForNrarfcn(chNumber);
+                break;
             default:
                 Rlog.w(TAG, "getBand: unknown WWAN RAT " + rat);
                 band = 0;
diff --git a/src/java/com/android/internal/telephony/metrics/VoiceCallSessionStats.java b/src/java/com/android/internal/telephony/metrics/VoiceCallSessionStats.java
index 4c6bff9..1a1bbf1 100644
--- a/src/java/com/android/internal/telephony/metrics/VoiceCallSessionStats.java
+++ b/src/java/com/android/internal/telephony/metrics/VoiceCallSessionStats.java
@@ -33,16 +33,6 @@
 import static com.android.internal.telephony.TelephonyStatsLog.VOICE_CALL_SESSION__MAIN_CODEC_QUALITY__CODEC_QUALITY_SUPER_WIDEBAND;
 import static com.android.internal.telephony.TelephonyStatsLog.VOICE_CALL_SESSION__MAIN_CODEC_QUALITY__CODEC_QUALITY_UNKNOWN;
 import static com.android.internal.telephony.TelephonyStatsLog.VOICE_CALL_SESSION__MAIN_CODEC_QUALITY__CODEC_QUALITY_WIDEBAND;
-import static com.android.internal.telephony.TelephonyStatsLog.VOICE_CALL_SESSION__SETUP_DURATION__CALL_SETUP_DURATION_EXTREMELY_FAST;
-import static com.android.internal.telephony.TelephonyStatsLog.VOICE_CALL_SESSION__SETUP_DURATION__CALL_SETUP_DURATION_EXTREMELY_SLOW;
-import static com.android.internal.telephony.TelephonyStatsLog.VOICE_CALL_SESSION__SETUP_DURATION__CALL_SETUP_DURATION_FAST;
-import static com.android.internal.telephony.TelephonyStatsLog.VOICE_CALL_SESSION__SETUP_DURATION__CALL_SETUP_DURATION_NORMAL;
-import static com.android.internal.telephony.TelephonyStatsLog.VOICE_CALL_SESSION__SETUP_DURATION__CALL_SETUP_DURATION_SLOW;
-import static com.android.internal.telephony.TelephonyStatsLog.VOICE_CALL_SESSION__SETUP_DURATION__CALL_SETUP_DURATION_ULTRA_FAST;
-import static com.android.internal.telephony.TelephonyStatsLog.VOICE_CALL_SESSION__SETUP_DURATION__CALL_SETUP_DURATION_ULTRA_SLOW;
-import static com.android.internal.telephony.TelephonyStatsLog.VOICE_CALL_SESSION__SETUP_DURATION__CALL_SETUP_DURATION_UNKNOWN;
-import static com.android.internal.telephony.TelephonyStatsLog.VOICE_CALL_SESSION__SETUP_DURATION__CALL_SETUP_DURATION_VERY_FAST;
-import static com.android.internal.telephony.TelephonyStatsLog.VOICE_CALL_SESSION__SETUP_DURATION__CALL_SETUP_DURATION_VERY_SLOW;
 import static com.android.internal.telephony.TelephonyStatsLog.VOICE_CALL_SESSION__SIGNAL_STRENGTH_AT_END__SIGNAL_STRENGTH_GREAT;
 import static com.android.internal.telephony.TelephonyStatsLog.VOICE_CALL_SESSION__SIGNAL_STRENGTH_AT_END__SIGNAL_STRENGTH_NONE_OR_UNKNOWN;
 
@@ -127,9 +117,6 @@
     /** Holds the audio codec value for IMS calls. */
     private static final SparseIntArray IMS_CODEC_MAP = buildImsCodecMap();
 
-    /** Holds setup duration buckets with values as their upper bounds in milliseconds. */
-    private static final SparseIntArray CALL_SETUP_DURATION_MAP = buildCallSetupDurationMap();
-
     /** Holds call duration buckets with values as their upper bounds in milliseconds. */
     private static final SparseIntArray CALL_DURATION_MAP = buildCallDurationMap();
 
@@ -414,7 +401,6 @@
             logd("acceptCall: resetting setup info, connectionId=%d", id);
             VoiceCallSession proto = mCallProtos.get(id);
             proto.setupBeginMillis = getTimeMillis();
-            proto.setupDuration = VOICE_CALL_SESSION__SETUP_DURATION__CALL_SETUP_DURATION_UNKNOWN;
         } else {
             loge("acceptCall: untracked connection, connectionId=%d", id);
         }
@@ -443,7 +429,6 @@
         proto.bearerAtStart = bearer;
         proto.bearerAtEnd = bearer;
         proto.direction = getDirection(conn);
-        proto.setupDuration = VOICE_CALL_SESSION__SETUP_DURATION__CALL_SETUP_DURATION_UNKNOWN;
         proto.setupFailed = true;
         proto.disconnectReasonCode = conn.getDisconnectCause();
         proto.disconnectExtraCode = conn.getPreciseDisconnectCause();
@@ -565,7 +550,6 @@
     private void checkCallSetup(Connection conn, VoiceCallSession proto) {
         if (proto.setupBeginMillis != 0L && isSetupFinished(conn.getCall())) {
             proto.setupDurationMillis = (int) (getTimeMillis() - proto.setupBeginMillis);
-            proto.setupDuration = classifySetupDuration(proto.setupDurationMillis);
             proto.setupBeginMillis = 0L;
         }
         // Clear setupFailed if call now active, but otherwise leave it unchanged
@@ -777,16 +761,6 @@
         }
     }
 
-    private static int classifySetupDuration(int durationMillis) {
-        // keys in CALL_SETUP_DURATION_MAP are upper bounds in ascending order
-        for (int i = 0; i < CALL_SETUP_DURATION_MAP.size(); i++) {
-            if (durationMillis < CALL_SETUP_DURATION_MAP.keyAt(i)) {
-                return CALL_SETUP_DURATION_MAP.valueAt(i);
-            }
-        }
-        return VOICE_CALL_SESSION__SETUP_DURATION__CALL_SETUP_DURATION_EXTREMELY_SLOW;
-    }
-
     private static int classifyCallDuration(long durationMillis) {
         if (durationMillis == 0L) {
             return VOICE_CALL_SESSION__CALL_DURATION__CALL_DURATION_UNKNOWN;
@@ -865,41 +839,6 @@
         return map;
     }
 
-    private static SparseIntArray buildCallSetupDurationMap() {
-        SparseIntArray map = new SparseIntArray();
-
-        map.put(
-                CALL_SETUP_DURATION_UNKNOWN,
-                VOICE_CALL_SESSION__SETUP_DURATION__CALL_SETUP_DURATION_UNKNOWN);
-        map.put(
-                CALL_SETUP_DURATION_EXTREMELY_FAST,
-                VOICE_CALL_SESSION__SETUP_DURATION__CALL_SETUP_DURATION_EXTREMELY_FAST);
-        map.put(
-                CALL_SETUP_DURATION_ULTRA_FAST,
-                VOICE_CALL_SESSION__SETUP_DURATION__CALL_SETUP_DURATION_ULTRA_FAST);
-        map.put(
-                CALL_SETUP_DURATION_VERY_FAST,
-                VOICE_CALL_SESSION__SETUP_DURATION__CALL_SETUP_DURATION_VERY_FAST);
-        map.put(
-                CALL_SETUP_DURATION_FAST,
-                VOICE_CALL_SESSION__SETUP_DURATION__CALL_SETUP_DURATION_FAST);
-        map.put(
-                CALL_SETUP_DURATION_NORMAL,
-                VOICE_CALL_SESSION__SETUP_DURATION__CALL_SETUP_DURATION_NORMAL);
-        map.put(
-                CALL_SETUP_DURATION_SLOW,
-                VOICE_CALL_SESSION__SETUP_DURATION__CALL_SETUP_DURATION_SLOW);
-        map.put(
-                CALL_SETUP_DURATION_VERY_SLOW,
-                VOICE_CALL_SESSION__SETUP_DURATION__CALL_SETUP_DURATION_VERY_SLOW);
-        map.put(
-                CALL_SETUP_DURATION_ULTRA_SLOW,
-                VOICE_CALL_SESSION__SETUP_DURATION__CALL_SETUP_DURATION_ULTRA_SLOW);
-        // anything above would be CALL_SETUP_DURATION_EXTREMELY_SLOW
-
-        return map;
-    }
-
     private static SparseIntArray buildCallDurationMap() {
         SparseIntArray map = new SparseIntArray();
 
diff --git a/src/java/com/android/internal/telephony/nitz/OWNERS b/src/java/com/android/internal/telephony/nitz/OWNERS
new file mode 100644
index 0000000..be0513d
--- /dev/null
+++ b/src/java/com/android/internal/telephony/nitz/OWNERS
@@ -0,0 +1,2 @@
+# Bug component: 847766
+include platform/frameworks/base:/services/core/java/com/android/server/timezonedetector/OWNERS
diff --git a/src/java/com/android/internal/telephony/uicc/AdnCapacity.java b/src/java/com/android/internal/telephony/uicc/AdnCapacity.java
index 479786c..f2cab4f 100644
--- a/src/java/com/android/internal/telephony/uicc/AdnCapacity.java
+++ b/src/java/com/android/internal/telephony/uicc/AdnCapacity.java
@@ -110,6 +110,21 @@
         return mMaxAdnCount > 0;
     }
 
+    @Override
+    public String toString() {
+        String capacity = "getAdnRecordsCapacity : max adn=" + mMaxAdnCount
+                + ", used adn=" + mUsedAdnCount
+                + ", max email=" + mMaxEmailCount
+                + ", used email=" + mUsedEmailCount
+                + ", max anr=" + mMaxAnrCount
+                + ", used anr=" + mUsedAnrCount
+                + ", max name length=" + mMaxNameLength
+                + ", max number length =" + mMaxNumberLength
+                + ", max email length =" + mMaxEmailLength
+                + ", max anr length =" + mMaxAnrLength;
+        return capacity;
+    }
+
     public static final Parcelable.Creator<AdnCapacity> CREATOR
             = new Parcelable.Creator<AdnCapacity>() {
         @Override
diff --git a/src/java/com/android/internal/telephony/uicc/IsimUiccRecords.java b/src/java/com/android/internal/telephony/uicc/IsimUiccRecords.java
index 1fe6223..12284af 100644
--- a/src/java/com/android/internal/telephony/uicc/IsimUiccRecords.java
+++ b/src/java/com/android/internal/telephony/uicc/IsimUiccRecords.java
@@ -67,9 +67,9 @@
         return "IsimUiccRecords: " + super.toString()
                 + (DUMP_RECORDS ? (" mIsimImpi=" + mIsimImpi
                 + " mIsimDomain=" + mIsimDomain
-                + " mIsimImpu=" + mIsimImpu
+                + " mIsimImpu=" + Arrays.toString(mIsimImpu)
                 + " mIsimIst=" + mIsimIst
-                + " mIsimPcscf=" + mIsimPcscf) : "");
+                + " mIsimPcscf=" + Arrays.toString(mIsimPcscf)) : "");
     }
 
     public IsimUiccRecords(UiccCardApplication app, Context c, CommandsInterface ci) {
@@ -437,7 +437,7 @@
             pw.println(" mIsimDomain=" + mIsimDomain);
             pw.println(" mIsimImpu[]=" + Arrays.toString(mIsimImpu));
             pw.println(" mIsimIst" + mIsimIst);
-            pw.println(" mIsimPcscf" + mIsimPcscf);
+            pw.println(" mIsimPcscf" + Arrays.toString(mIsimPcscf));
         }
         pw.flush();
     }
diff --git a/src/java/com/android/internal/telephony/uicc/RuimRecords.java b/src/java/com/android/internal/telephony/uicc/RuimRecords.java
index f905bdc..08c1573 100755
--- a/src/java/com/android/internal/telephony/uicc/RuimRecords.java
+++ b/src/java/com/android/internal/telephony/uicc/RuimRecords.java
@@ -81,8 +81,8 @@
                 + " mMyMobileNumber=" + "xxxx"
                 + " mMin2Min1=" + mMin2Min1
                 + " mPrlVersion=" + mPrlVersion
-                + " mEFpl=" + mEFpl
-                + " mEFli=" + mEFli
+                + " mEFpl=" + IccUtils.bytesToHexString(mEFpl)
+                + " mEFli=" + IccUtils.bytesToHexString(mEFli)
                 + " mCsimSpnDisplayCondition=" + mCsimSpnDisplayCondition
                 + " mMdn=" + mMdn
                 + " mMin=" + mMin
diff --git a/src/java/com/android/internal/telephony/uicc/SIMRecords.java b/src/java/com/android/internal/telephony/uicc/SIMRecords.java
index 9958bfb..b6032ec 100644
--- a/src/java/com/android/internal/telephony/uicc/SIMRecords.java
+++ b/src/java/com/android/internal/telephony/uicc/SIMRecords.java
@@ -102,12 +102,12 @@
                 + " mVmConfig" + mVmConfig
                 + " callForwardingEnabled=" + mCallForwardingStatus
                 + " spnState=" + mSpnState
-                + " mCphsInfo=" + mCphsInfo
+                + " mCphsInfo=" + IccUtils.bytesToHexString(mCphsInfo)
                 + " mCspPlmnEnabled=" + mCspPlmnEnabled
-                + " efMWIS=" + mEfMWIS
-                + " efCPHS_MWI=" + mEfCPHS_MWI
-                + " mEfCff=" + mEfCff
-                + " mEfCfis=" + mEfCfis
+                + " efMWIS=" + IccUtils.bytesToHexString(mEfMWIS)
+                + " efCPHS_MWI=" + IccUtils.bytesToHexString(mEfCPHS_MWI)
+                + " mEfCff=" + IccUtils.bytesToHexString(mEfCff)
+                + " mEfCfis=" + IccUtils.bytesToHexString(mEfCfis)
                 + " getOperatorNumeric=" + getOperatorNumeric();
     }
 
@@ -1970,7 +1970,7 @@
             // Byte 5 and 6 are for lacTacEnd.
             // Byte 7 is for PNN Record Identifier.
             if (data.length != 8) {
-                loge("Invalid length for OPL record " + data);
+                loge("Invalid length for OPL record " + IccUtils.bytesToHexString(data));
                 continue;
             }
 
@@ -2118,14 +2118,14 @@
         pw.println(" mVmConfig=" + mVmConfig);
         pw.println(" mCallForwardingStatus=" + mCallForwardingStatus);
         pw.println(" mSpnState=" + mSpnState);
-        pw.println(" mCphsInfo=" + mCphsInfo);
+        pw.println(" mCphsInfo=" + IccUtils.bytesToHexString(mCphsInfo));
         pw.println(" mCspPlmnEnabled=" + mCspPlmnEnabled);
         pw.println(" mEfMWIS[]=" + Arrays.toString(mEfMWIS));
         pw.println(" mEfCPHS_MWI[]=" + Arrays.toString(mEfCPHS_MWI));
         pw.println(" mEfCff[]=" + Arrays.toString(mEfCff));
         pw.println(" mEfCfis[]=" + Arrays.toString(mEfCfis));
         pw.println(" mCarrierNameDisplayCondition=" + mCarrierNameDisplayCondition);
-        pw.println(" mSpdi[]=" + mSpdi);
+        pw.println(" mSpdi[]=" + Arrays.toString(mSpdi));
         pw.println(" mUsimServiceTable=" + mUsimServiceTable);
         pw.println(" mGid1=" + mGid1);
         if (mCarrierTestOverride.isInTestMode()) {
diff --git a/src/java/com/android/internal/telephony/uicc/SimPhonebookRecordCache.java b/src/java/com/android/internal/telephony/uicc/SimPhonebookRecordCache.java
index e06e008..149e605 100644
--- a/src/java/com/android/internal/telephony/uicc/SimPhonebookRecordCache.java
+++ b/src/java/com/android/internal/telephony/uicc/SimPhonebookRecordCache.java
@@ -442,17 +442,20 @@
             if (!newCapacity.isSimEmpty()){
                 mIsCacheInvalidated.set(true);
                 fillCacheWithoutWaiting();
-            } else {
+            } else if (newCapacity.isSimValid()) {
                 notifyAdnLoadingWaiters();
+                tryFireUpdatePendingList();
+            } else {
+                logd("ADN capacity is invalid");
             }
             mIsInitialized.set(true); // Let's say the whole process is ready
         } else {
             // There is nothing from PB, so notify waiters directly if any
-            if (newCapacity.isSimEmpty()
-                    || !newCapacity.isSimValid()) {
+            if (newCapacity.isSimValid() && newCapacity.isSimEmpty()) {
                 mIsCacheInvalidated.set(false);
                 notifyAdnLoadingWaiters();
-            } else if (!mIsUpdateDone) {
+                tryFireUpdatePendingList();
+            } else if (!mIsUpdateDone && !newCapacity.isSimEmpty()) {
                 invalidateSimPbCache();
                 fillCacheWithoutWaiting();
             }
diff --git a/src/java/com/android/internal/telephony/uicc/UiccCarrierPrivilegeRules.java b/src/java/com/android/internal/telephony/uicc/UiccCarrierPrivilegeRules.java
index 08521e6..7d87e5f 100644
--- a/src/java/com/android/internal/telephony/uicc/UiccCarrierPrivilegeRules.java
+++ b/src/java/com/android/internal/telephony/uicc/UiccCarrierPrivilegeRules.java
@@ -495,7 +495,8 @@
                         }
                     } else {
                         if (mAIDInUse == ARAM) {
-                            String errorMsg = "Invalid response: payload=" + response.payload
+                            String errorMsg = "Invalid response: payload="
+                                    + IccUtils.bytesToHexString(response.payload)
                                     + " sw1=" + response.sw1 + " sw2=" + response.sw2;
                             updateState(STATE_ERROR, errorMsg);
                         }
diff --git a/tests/telephonytests/src/com/android/internal/telephony/CarrierActionAgentTest.java b/tests/telephonytests/src/com/android/internal/telephony/CarrierActionAgentTest.java
index 7727e79..4f91994 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/CarrierActionAgentTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/CarrierActionAgentTest.java
@@ -92,6 +92,7 @@
         final Intent intent = new Intent(TelephonyIntents.ACTION_SIM_STATE_CHANGED);
         intent.putExtra(IccCardConstants.INTENT_KEY_ICC_STATE,
                 IccCardConstants.INTENT_VALUE_ICC_LOADED);
+        intent.putExtra(PhoneConstants.PHONE_KEY, mPhone.getPhoneId());
         mContext.sendBroadcast(intent);
         processAllMessages();
 
@@ -134,6 +135,7 @@
         final Intent intent = new Intent(TelephonyIntents.ACTION_SIM_STATE_CHANGED);
         intent.putExtra(IccCardConstants.INTENT_KEY_ICC_STATE,
                 IccCardConstants.INTENT_VALUE_ICC_LOADED);
+        intent.putExtra(PhoneConstants.PHONE_KEY, mPhone.getPhoneId());
         mContext.sendBroadcast(intent);
         processAllMessages();
 
diff --git a/tests/telephonytests/src/com/android/internal/telephony/GsmCdmaCallTrackerTest.java b/tests/telephonytests/src/com/android/internal/telephony/GsmCdmaCallTrackerTest.java
index 33a8e62..f0c43be 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/GsmCdmaCallTrackerTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/GsmCdmaCallTrackerTest.java
@@ -42,6 +42,9 @@
 
 import com.android.internal.telephony.PhoneInternalInterface.DialArgs;
 
+import java.io.PrintWriter;
+import java.io.StringWriter;
+
 import org.junit.After;
 import org.junit.Assert;
 import org.junit.Before;
@@ -109,7 +112,9 @@
             processAllMessages();
         } catch(Exception ex) {
             ex.printStackTrace();
-            Assert.fail("unexpected exception thrown"+ex.getMessage()+ex.getStackTrace());
+            StringWriter exString = new StringWriter();
+            ex.printStackTrace(new PrintWriter(exString));
+            Assert.fail("unexpected exception thrown" + exString);
         }
 
         assertEquals(PhoneConstants.State.OFFHOOK, mCTUT.getState());
diff --git a/tests/telephonytests/src/com/android/internal/telephony/NitzDataTest.java b/tests/telephonytests/src/com/android/internal/telephony/NitzDataTest.java
index 2460dba..05bcc5f 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/NitzDataTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/NitzDataTest.java
@@ -29,8 +29,17 @@
 public class NitzDataTest {
 
     @Test
-    public void testParse_dateOutsideAllowedRange() {
-        assertNull(NitzData.parse("38/06/20,00:00:00+0"));
+    public void testParse_invalidYear() {
+        assertNull(NitzData.parse("00/06/20,00:00:00+0,0"));
+    }
+
+    @Test
+    public void testParse_beyond2038() {
+        NitzData nitz = NitzData.parse("40/06/20,01:02:03+4,1");
+        assertEquals(createUnixEpochTime(2040, 6, 20, 1, 2, 3), nitz.getCurrentTimeInMillis());
+        assertEquals(TimeUnit.MINUTES.toMillis(4 * 15), nitz.getLocalOffsetMillis());
+        assertEquals(TimeUnit.MINUTES.toMillis(60), nitz.getDstAdjustmentMillis().longValue());
+        assertNull(nitz.getEmulatorHostTimeZone());
     }
 
     @Test
@@ -38,7 +47,7 @@
         // "yy/mm/dd,hh:mm:ss(+/-)tz[,dt[,tzid]]"
 
         // No tz field.
-        assertNull(NitzData.parse("38/06/20,00:00:00"));
+        assertNull(NitzData.parse("22/06/20,00:00:00"));
     }
 
     @Test
diff --git a/tests/telephonytests/src/com/android/internal/telephony/ServiceStateTrackerTest.java b/tests/telephonytests/src/com/android/internal/telephony/ServiceStateTrackerTest.java
index ce2a260..0cad6ee 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/ServiceStateTrackerTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/ServiceStateTrackerTest.java
@@ -1869,12 +1869,6 @@
     @SmallTest
     public void testSetTimeFromNITZStr_withoutAge() throws Exception {
         {
-            // Mock sending incorrect nitz str from RIL
-            mSimulatedCommands.triggerNITZupdate("38/06/20,00:00:00+0");
-            waitForLastHandlerAction(mSSTTestHandler.getThreadHandler());
-            verify(mNitzStateMachine, times(0)).handleNitzReceived(any());
-        }
-        {
             // 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);
@@ -1899,13 +1893,6 @@
     @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;
diff --git a/tests/telephonytests/src/com/android/internal/telephony/SimSmsTest.java b/tests/telephonytests/src/com/android/internal/telephony/SimSmsTest.java
index 0bacc1d..48406de 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/SimSmsTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/SimSmsTest.java
@@ -42,7 +42,6 @@
         List<SmsRawData> records = sms.getAllMessagesFromIccEfForSubscriber(
                 preferredSmsSubscription, ActivityThread.currentPackageName());
         assertNotNull(records);
-        assertTrue(records.size() >= 0);
 
         int firstNullIndex = -1;
         int firstValidIndex = -1;
diff --git a/tests/telephonytests/src/com/android/internal/telephony/SimulatedCommands.java b/tests/telephonytests/src/com/android/internal/telephony/SimulatedCommands.java
index 1a2952c..6a075da 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/SimulatedCommands.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/SimulatedCommands.java
@@ -181,6 +181,7 @@
     private boolean mDcSuccess = true;
     private SetupDataCallResult mSetupDataCallResult;
     private boolean mIsRadioPowerFailResponse = false;
+    private boolean mIsReportSmsMemoryStatusFailResponse = false;
 
     public boolean mSetRadioPowerForEmergencyCall;
     public boolean mSetRadioPowerAsSelectedPhoneForEmergencyCall;
@@ -1298,10 +1299,19 @@
 
     @Override
     public void reportSmsMemoryStatus(boolean available, Message result) {
-        resultSuccess(result, null);
+        if (!mIsReportSmsMemoryStatusFailResponse) {
+            resultSuccess(result, null);
+        } else {
+            CommandException ex = new CommandException(CommandException.Error.GENERIC_FAILURE);
+            resultFail(result, null, ex);
+        }
         SimulatedCommandsVerifier.getInstance().reportSmsMemoryStatus(available, result);
     }
 
+    public void setReportSmsMemoryStatusFailResponse(boolean fail) {
+        mIsReportSmsMemoryStatusFailResponse = fail;
+    }
+
     @Override
     public void reportStkServiceIsRunning(Message result) {
         resultSuccess(result, null);
diff --git a/tests/telephonytests/src/com/android/internal/telephony/SmsStorageMonitorTest.java b/tests/telephonytests/src/com/android/internal/telephony/SmsStorageMonitorTest.java
index 4b22f5f..3eace63 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/SmsStorageMonitorTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/SmsStorageMonitorTest.java
@@ -16,12 +16,15 @@
 
 package com.android.internal.telephony;
 
+import static com.android.internal.telephony.TelephonyTestUtils.waitForMs;
+
 import static org.junit.Assert.*;
 import static org.mockito.Mockito.*;
 
 import android.content.Intent;
 import android.os.Message;
 import android.provider.Telephony;
+import android.test.suitebuilder.annotation.MediumTest;
 import android.test.suitebuilder.annotation.SmallTest;
 import android.testing.AndroidTestingRunner;
 import android.testing.TestableLooper;
@@ -36,12 +39,17 @@
 @TestableLooper.RunWithLooper
 public class SmsStorageMonitorTest extends TelephonyTest {
 
+    private static final int MAX_RETRIES = 1;
+    private static final int RETRY_DELAY = 200; // 200 millis
+
     private SmsStorageMonitor mSmsStorageMonitor;
 
     @Before
     public void setUp() throws Exception {
         super.setUp(getClass().getSimpleName());
         mSmsStorageMonitor = new SmsStorageMonitor(mPhone);
+        mSmsStorageMonitor.setMaxRetries(MAX_RETRIES);
+        mSmsStorageMonitor.setRetryDelayInMillis(RETRY_DELAY);
         processAllMessages();
     }
 
@@ -99,4 +107,54 @@
 
         verify(mSimulatedCommandsVerifier).reportSmsMemoryStatus(eq(true), any(Message.class));
     }
-}
\ No newline at end of file
+
+    @Test @MediumTest
+    public void testRetrySmsMemoryStatus() {
+        mSimulatedCommands.setReportSmsMemoryStatusFailResponse(true);
+
+        // Send DEVICE_STORAGE_FULL
+        mContextFixture.getTestDouble().sendBroadcast(
+                new Intent(Intent.ACTION_DEVICE_STORAGE_FULL));
+        processAllMessages();
+
+        // Wait until retrying is done.
+        for (int i = 0; i < MAX_RETRIES; i++) {
+            waitForMs(RETRY_DELAY);
+            processAllMessages();
+        }
+
+        verify(mSimulatedCommandsVerifier, times(1 + MAX_RETRIES))
+                .reportSmsMemoryStatus(eq(false), any(Message.class));
+        assertFalse(mSmsStorageMonitor.isStorageAvailable());
+
+        mSimulatedCommands.setReportSmsMemoryStatusFailResponse(false);
+
+        // Notify radio on
+        mSimulatedCommands.notifyRadioOn();
+        processAllMessages();
+
+        verify(mSimulatedCommandsVerifier, times(2 + MAX_RETRIES))
+                .reportSmsMemoryStatus(eq(false), any(Message.class));
+    }
+
+    @Test @SmallTest
+    public void testReportSmsMemoryStatusDuringRetry() {
+        mSimulatedCommands.setReportSmsMemoryStatusFailResponse(true);
+
+        // Send DEVICE_STORAGE_FULL
+        mContextFixture.getTestDouble().sendBroadcast(
+                new Intent(Intent.ACTION_DEVICE_STORAGE_FULL));
+        processAllMessages();
+
+        mSimulatedCommands.setReportSmsMemoryStatusFailResponse(false);
+
+        // Send DEVICE_STORAGE_NOT_FULL
+        mContextFixture.getTestDouble().sendBroadcast(
+                new Intent(Intent.ACTION_DEVICE_STORAGE_NOT_FULL));
+        processAllMessages();
+
+        verify(mSimulatedCommandsVerifier).reportSmsMemoryStatus(eq(false), any(Message.class));
+        verify(mSimulatedCommandsVerifier).reportSmsMemoryStatus(eq(true), any(Message.class));
+        assertTrue(mSmsStorageMonitor.isStorageAvailable());
+    }
+}
diff --git a/tests/telephonytests/src/com/android/internal/telephony/SubscriptionControllerTest.java b/tests/telephonytests/src/com/android/internal/telephony/SubscriptionControllerTest.java
index ea02a4d..38a2454 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/SubscriptionControllerTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/SubscriptionControllerTest.java
@@ -166,7 +166,6 @@
          * between each test case. */
         if (mSubscriptionControllerUT != null) {
             mSubscriptionControllerUT.clearSubInfo();
-            mSubscriptionControllerUT.resetStaticMembers();
             mSubscriptionControllerUT = null;
         }
 
@@ -1384,7 +1383,8 @@
 
         int[] subIds = mSubscriptionControllerUT.getActiveSubIdList(/*visibleOnly*/false);
         // Make sure the return sub ids are sorted by slot index
-        assertTrue("active sub ids = " + subIds, Arrays.equals(subIds, new int[]{2, 1}));
+        assertTrue("active sub ids = " + Arrays.toString(subIds),
+                Arrays.equals(subIds, new int[]{2, 1}));
     }
 
     @Test
diff --git a/tests/telephonytests/src/com/android/internal/telephony/SubscriptionInfoUpdaterTest.java b/tests/telephonytests/src/com/android/internal/telephony/SubscriptionInfoUpdaterTest.java
index ea38e2d..c669810 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/SubscriptionInfoUpdaterTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/SubscriptionInfoUpdaterTest.java
@@ -794,6 +794,38 @@
 
     @Test
     @SmallTest
+    public void testOpportunisticSubscriptionNotUnsetWithEmptyConfigKey() throws Exception {
+        final int phoneId = mPhone.getPhoneId();
+        PersistableBundle carrierConfig = new PersistableBundle();
+
+        String carrierPackageName = "FakeCarrierPackageName";
+
+        doReturn(FAKE_SUB_ID_1).when(mSubscriptionController).getSubIdUsingPhoneId(phoneId);
+        doReturn(mSubInfo).when(mSubscriptionController).getSubscriptionInfo(eq(FAKE_SUB_ID_1));
+        doReturn(true).when(mSubInfo).isOpportunistic();
+        doReturn(carrierPackageName).when(mTelephonyManager)
+                .getCarrierServicePackageNameForLogicalSlot(eq(phoneId));
+        ((MockContentResolver) mContext.getContentResolver()).addProvider(
+                SubscriptionManager.CONTENT_URI.getAuthority(),
+                new FakeSubscriptionContentProvider());
+
+        mUpdater.updateSubscriptionByCarrierConfig(mPhone.getPhoneId(),
+                carrierPackageName, carrierConfig);
+
+        ArgumentCaptor<ContentValues> cvCaptor = ArgumentCaptor.forClass(ContentValues.class);
+        verify(mContentProvider, times(1)).update(
+                eq(SubscriptionManager.getUriForSubscriptionId(FAKE_SUB_ID_1)),
+                cvCaptor.capture(), eq(null), eq(null));
+        // no key is added for the opportunistic bit
+        assertNull(cvCaptor.getValue().getAsInteger(SubscriptionManager.IS_OPPORTUNISTIC));
+        // only carrier certs updated
+        assertEquals(1, cvCaptor.getValue().size());
+        verify(mSubscriptionController, times(1)).refreshCachedActiveSubscriptionInfoList();
+        verify(mSubscriptionController, times(1)).notifySubscriptionInfoChanged();
+    }
+
+    @Test
+    @SmallTest
     public void testUpdateFromCarrierConfigOpportunisticAddToGroup() throws Exception {
         final int phoneId = mPhone.getPhoneId();
         PersistableBundle carrierConfig = getCarrierConfigForSubInfoUpdate(
diff --git a/tests/telephonytests/src/com/android/internal/telephony/TelephonyRegistryTest.java b/tests/telephonytests/src/com/android/internal/telephony/TelephonyRegistryTest.java
index dbb371b..cf7cadb 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/TelephonyRegistryTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/TelephonyRegistryTest.java
@@ -43,8 +43,12 @@
 import android.os.UserHandle;
 import android.telephony.AccessNetworkConstants;
 import android.telephony.Annotation;
+import android.telephony.BarringInfo;
 import android.telephony.CellIdentity;
 import android.telephony.CellIdentityGsm;
+import android.telephony.CellIdentityLte;
+import android.telephony.CellInfo;
+import android.telephony.CellInfoLte;
 import android.telephony.CellLocation;
 import android.telephony.LinkCapacityEstimate;
 import android.telephony.NetworkRegistrationInfo;
@@ -62,6 +66,7 @@
 import android.testing.AndroidTestingRunner;
 import android.testing.TestableLooper;
 import android.text.TextUtils;
+import android.util.SparseArray;
 
 import androidx.annotation.NonNull;
 
@@ -73,6 +78,7 @@
 import org.junit.runner.RunWith;
 
 import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.Collections;
 import java.util.HashSet;
 import java.util.List;
@@ -100,6 +106,8 @@
     private int mNetworkType = TelephonyManager.NETWORK_TYPE_UNKNOWN;
     private List<PhysicalChannelConfig> mPhysicalChannelConfigs;
     private CellLocation mCellLocation;
+    private List<CellInfo> mCellInfo;
+    private BarringInfo mBarringInfo = null;
 
     // All events contribute to TelephonyRegistry#isPhoneStatePermissionRequired
     private static final Set<Integer> READ_PHONE_STATE_EVENTS;
@@ -166,7 +174,9 @@
             TelephonyCallback.LinkCapacityEstimateChangedListener,
             TelephonyCallback.PhysicalChannelConfigListener,
             TelephonyCallback.CellLocationListener,
-            TelephonyCallback.ServiceStateListener {
+            TelephonyCallback.ServiceStateListener,
+            TelephonyCallback.CellInfoListener,
+            TelephonyCallback.BarringInfoListener {
         // This class isn't mockable to get invocation counts because the IBinder is null and
         // crashes the TelephonyRegistry. Make a cheesy verify(times()) alternative.
         public AtomicInteger invocationCount = new AtomicInteger(0);
@@ -228,6 +238,18 @@
         public void onPhysicalChannelConfigChanged(@NonNull List<PhysicalChannelConfig> configs) {
             mPhysicalChannelConfigs = configs;
         }
+
+        @Override
+        public void onCellInfoChanged(List<CellInfo> cellInfo) {
+            invocationCount.incrementAndGet();
+            mCellInfo = cellInfo;
+        }
+
+        @Override
+        public void onBarringInfoChanged(BarringInfo barringInfo) {
+            invocationCount.incrementAndGet();
+            mBarringInfo = barringInfo;
+        }
     }
 
     private void addTelephonyRegistryService() {
@@ -874,6 +896,43 @@
         assertEquals(PHYSICAL_CELL_ID_UNKNOWN, mPhysicalChannelConfigs.get(0).getPhysicalCellId());
     }
 
+    @Test
+    public void testBarringInfoChanged() {
+        // Return a slotIndex / phoneId of 0 for all sub ids given.
+        doReturn(mMockSubInfo).when(mSubscriptionManager).getActiveSubscriptionInfo(anyInt());
+        doReturn(0/*slotIndex*/).when(mMockSubInfo).getSimSlotIndex();
+        doReturn(true).when(mLocationManager).isLocationEnabledForUser(any(UserHandle.class));
+
+        final int subId = 1;
+        int[] events = {TelephonyCallback.EVENT_BARRING_INFO_CHANGED};
+        SparseArray<BarringInfo.BarringServiceInfo> bsi = new SparseArray(1);
+        bsi.set(BarringInfo.BARRING_SERVICE_TYPE_MO_DATA,
+                new BarringInfo.BarringServiceInfo(
+                        BarringInfo.BarringServiceInfo.BARRING_TYPE_CONDITIONAL,
+                        false /*isConditionallyBarred*/,
+                        30 /*conditionalBarringFactor*/,
+                        10 /*conditionalBarringTimeSeconds*/));
+        BarringInfo info = new BarringInfo(new CellIdentityLte(), bsi);
+
+        // Registering for info causes Barring Info to be sent to caller
+        mTelephonyRegistry.listenWithEventList(false, false, subId, mContext.getOpPackageName(),
+                mContext.getAttributionTag(), mTelephonyCallback.callback, events, true);
+        processAllMessages();
+        assertEquals(1, mTelephonyCallback.invocationCount.get());
+        assertNotNull(mBarringInfo);
+
+        // Updating the barring info causes Barring Info to be updated
+        mTelephonyRegistry.notifyBarringInfoChanged(0, subId, info);
+        processAllMessages();
+        assertEquals(2, mTelephonyCallback.invocationCount.get());
+        assertEquals(mBarringInfo, info);
+
+        // Duplicate BarringInfo notifications do not trigger callback
+        mTelephonyRegistry.notifyBarringInfoChanged(0, subId, info);
+        processAllMessages();
+        assertEquals(2, mTelephonyCallback.invocationCount.get());
+    }
+
     /**
      * Test listen to events that require READ_PHONE_STATE permission.
      */
@@ -1260,4 +1319,28 @@
 
         assertEquals(1, mTelephonyCallback.invocationCount.get());
     }
+
+    @Test @SmallTest
+    public void testCellInfoChanged() {
+        final int subId = 1;
+        final int[] events = {TelephonyCallback.EVENT_CELL_INFO_CHANGED};
+        final List<CellInfo> dummyCellInfo = Arrays.asList(new CellInfoLte());
+
+        mCellInfo = null; // null is an invalid value since the API is NonNull;
+
+        doReturn(mMockSubInfo).when(mSubscriptionManager).getActiveSubscriptionInfo(anyInt());
+        doReturn(0 /*slotIndex*/).when(mMockSubInfo).getSimSlotIndex();
+        doReturn(true).when(mLocationManager).isLocationEnabledForUser(any(UserHandle.class));
+
+        mTelephonyRegistry.listenWithEventList(false, false, subId, mContext.getOpPackageName(),
+                mContext.getAttributionTag(), mTelephonyCallback.callback, events, true);
+        processAllMessages();
+        assertEquals(1, mTelephonyCallback.invocationCount.get());
+        assertNotNull(mCellInfo);
+
+        mTelephonyRegistry.notifyCellInfoForSubscriber(subId, dummyCellInfo);
+        processAllMessages();
+        assertEquals(2, mTelephonyCallback.invocationCount.get());
+        assertEquals(mCellInfo, dummyCellInfo);
+    }
 }
diff --git a/tests/telephonytests/src/com/android/internal/telephony/TelephonyTest.java b/tests/telephonytests/src/com/android/internal/telephony/TelephonyTest.java
index 9b54b19..6aed4cf 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/TelephonyTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/TelephonyTest.java
@@ -33,6 +33,7 @@
 import android.app.AppOpsManager;
 import android.app.IActivityManager;
 import android.app.KeyguardManager;
+import android.app.PropertyInvalidatedCache;
 import android.app.usage.NetworkStatsManager;
 import android.content.ContentProvider;
 import android.content.ContentResolver;
@@ -501,7 +502,7 @@
         mMockedWlanDataServiceManager = Mockito.mock(DataServiceManager.class);
 
         TelephonyManager.disableServiceHandleCaching();
-        SubscriptionController.disableCaching();
+        PropertyInvalidatedCache.disableForTestMode();
         // For testing do not allow Log.WTF as it can cause test process to crash
         Log.setWtfHandler((tagString, what, system) -> Log.d(TAG, "WTF captured, ignoring. Tag: "
                 + tagString + ", exception: " + what));
@@ -898,7 +899,6 @@
         }
         restoreInstances();
         TelephonyManager.enableServiceHandleCaching();
-        SubscriptionController.enableCaching();
 
         mNetworkRegistrationInfo = null;
         mActivityManager = null;
diff --git a/tests/telephonytests/src/com/android/internal/telephony/cdma/CdmaInboundSmsHandlerTest.java b/tests/telephonytests/src/com/android/internal/telephony/cdma/CdmaInboundSmsHandlerTest.java
index f86dd4b..5df94e5 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/cdma/CdmaInboundSmsHandlerTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/cdma/CdmaInboundSmsHandlerTest.java
@@ -57,6 +57,11 @@
 import com.android.internal.util.IState;
 import com.android.internal.util.StateMachine;
 
+import java.io.PrintWriter;
+import java.io.StringWriter;
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+
 import org.junit.After;
 import org.junit.Before;
 import org.junit.Ignore;
@@ -64,9 +69,6 @@
 import org.junit.runner.RunWith;
 import org.mockito.ArgumentCaptor;
 
-import java.lang.reflect.Field;
-import java.lang.reflect.Method;
-
 @RunWith(AndroidTestingRunner.class)
 @TestableLooper.RunWithLooper
 public class CdmaInboundSmsHandlerTest extends TelephonyTest {
@@ -111,7 +113,9 @@
         try {
             doReturn(new int[]{UserHandle.USER_SYSTEM}).when(mIActivityManager).getRunningUserIds();
         } catch (RemoteException re) {
-            fail("Unexpected RemoteException: " + re.getStackTrace());
+            StringWriter reString = new StringWriter();
+            re.printStackTrace(new PrintWriter(reString));
+            fail("Unexpected RemoteException: " + reString);
         }
 
         mSmsMessage.mWrappedSmsMessage = mCdmaSmsMessage;
diff --git a/tests/telephonytests/src/com/android/internal/telephony/data/DataNetworkControllerTest.java b/tests/telephonytests/src/com/android/internal/telephony/data/DataNetworkControllerTest.java
index 399fd9f..d5abf0f 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/data/DataNetworkControllerTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/data/DataNetworkControllerTest.java
@@ -76,7 +76,6 @@
 import android.telephony.SubscriptionPlan;
 import android.telephony.TelephonyDisplayInfo;
 import android.telephony.TelephonyManager;
-import android.telephony.TelephonyProtoEnums;
 import android.telephony.data.ApnSetting;
 import android.telephony.data.DataCallResponse;
 import android.telephony.data.DataCallResponse.LinkStatus;
@@ -524,6 +523,20 @@
     private void serviceStateChanged(@NetworkType int networkType,
             @RegistrationState int dataRegState, @RegistrationState int voiceRegState,
             @RegistrationState int iwlanRegState, DataSpecificRegistrationInfo dsri) {
+        ServiceState ss = createSS(networkType, networkType, dataRegState, voiceRegState,
+                iwlanRegState, dsri);
+
+        doReturn(ss).when(mSST).getServiceState();
+        doReturn(ss).when(mPhone).getServiceState();
+
+        mDataNetworkControllerUT.obtainMessage(17/*EVENT_SERVICE_STATE_CHANGED*/).sendToTarget();
+        processAllMessages();
+    }
+
+    private ServiceState createSS(@NetworkType int dataNetworkType,
+            @NetworkType int voiceNetworkType,
+            @RegistrationState int dataRegState, @RegistrationState int voiceRegState,
+            @RegistrationState int iwlanRegState, DataSpecificRegistrationInfo dsri) {
         if (dsri == null) {
             dsri = new DataSpecificRegistrationInfo(8, false, true, true,
                     new LteVopsSupportInfo(LteVopsSupportInfo.LTE_STATUS_SUPPORTED,
@@ -534,7 +547,7 @@
 
         ss.addNetworkRegistrationInfo(new NetworkRegistrationInfo.Builder()
                 .setTransportType(AccessNetworkConstants.TRANSPORT_TYPE_WWAN)
-                .setAccessNetworkTechnology(networkType)
+                .setAccessNetworkTechnology(dataNetworkType)
                 .setRegistrationState(dataRegState)
                 .setDomain(NetworkRegistrationInfo.DOMAIN_PS)
                 .setDataSpecificInfo(dsri)
@@ -549,19 +562,15 @@
 
         ss.addNetworkRegistrationInfo(new NetworkRegistrationInfo.Builder()
                 .setTransportType(AccessNetworkConstants.TRANSPORT_TYPE_WWAN)
-                .setAccessNetworkTechnology(networkType)
+                .setAccessNetworkTechnology(voiceNetworkType)
                 .setRegistrationState(voiceRegState)
                 .setDomain(NetworkRegistrationInfo.DOMAIN_CS)
                 .build());
+
         ss.setDataRoamingFromRegistration(dataRegState
                 == NetworkRegistrationInfo.REGISTRATION_STATE_ROAMING);
         processServiceStateRegStateForTest(ss);
-
-        doReturn(ss).when(mSST).getServiceState();
-        doReturn(ss).when(mPhone).getServiceState();
-
-        mDataNetworkControllerUT.obtainMessage(17/*EVENT_SERVICE_STATE_CHANGED*/).sendToTarget();
-        processAllMessages();
+        return ss;
     }
 
     // set SS reg state base on SST impl, where WLAN overrides WWAN's data reg.
@@ -3373,6 +3382,38 @@
     }
 
     @Test
+    public void testHandoverDataNetworkSourceOosNoUnknownRule() throws Exception {
+        testSetupImsDataNetwork();
+        // Configured handover is allowed from OOS to 4G/5G/IWLAN.
+        mCarrierConfig.putStringArray(
+                CarrierConfigManager.KEY_IWLAN_HANDOVER_POLICY_STRING_ARRAY,
+                new String[]{
+                        "source=EUTRAN|NGRAN|IWLAN, target=EUTRAN|NGRAN|IWLAN, "
+                                + "type=disallowed, capabilities=IMS|EIMS|MMS|XCAP|CBS"
+                });
+        carrierConfigChanged();
+        serviceStateChanged(TelephonyManager.NETWORK_TYPE_LTE,
+                NetworkRegistrationInfo.REGISTRATION_STATE_NOT_REGISTERED_OR_SEARCHING);
+
+        updateTransport(NetworkCapabilities.NET_CAPABILITY_IMS,
+                AccessNetworkConstants.TRANSPORT_TYPE_WLAN);
+
+        // Verify IMS network was torn down on source first.
+        verify(mMockedWwanDataServiceManager).deactivateDataCall(anyInt(),
+                eq(DataService.REQUEST_REASON_NORMAL), any(Message.class));
+
+        // Verify that IWLAN is brought up again on IWLAN.
+        verify(mMockedWlanDataServiceManager).setupDataCall(anyInt(),
+                any(DataProfile.class), anyBoolean(), anyBoolean(),
+                eq(DataService.REQUEST_REASON_NORMAL), any(), anyInt(), any(), any(), anyBoolean(),
+                any(Message.class));
+
+        DataNetwork dataNetwork = getDataNetworks().get(0);
+        assertThat(dataNetwork.getTransport()).isEqualTo(
+                AccessNetworkConstants.TRANSPORT_TYPE_WLAN);
+    }
+
+    @Test
     public void testHandoverDataNetworkNonVops() throws Exception {
         ServiceState ss = new ServiceState();
 
@@ -3792,7 +3833,7 @@
         mDataNetworkControllerUT.addNetworkRequest(request);
         processAllMessages();
 
-        // Now DDS temporarily switched to phone 1
+        // this slot is 0, modem preferred on slot 1
         doReturn(1).when(mMockedPhoneSwitcher).getPreferredDataPhoneId();
 
         // Simulate telephony network factory remove request due to switch.
@@ -3805,13 +3846,13 @@
 
     @Test
     public void testSetupDataOnNonDds() throws Exception {
-        // Now DDS switched to phone 1
+        // this slot is 0, modem preferred on slot 1
         doReturn(1).when(mMockedPhoneSwitcher).getPreferredDataPhoneId();
         TelephonyNetworkRequest request = createNetworkRequest(
                 NetworkCapabilities.NET_CAPABILITY_MMS);
 
         // Test Don't allow setup if both data and voice OOS
-        serviceStateChanged(TelephonyProtoEnums.NETWORK_TYPE_1XRTT,
+        serviceStateChanged(TelephonyManager.NETWORK_TYPE_1xRTT,
                 // data, voice, Iwlan reg state
                 NetworkRegistrationInfo.REGISTRATION_STATE_NOT_REGISTERED_OR_SEARCHING,
                 NetworkRegistrationInfo.REGISTRATION_STATE_NOT_REGISTERED_OR_SEARCHING,
@@ -3822,18 +3863,24 @@
         verifyAllDataDisconnected();
 
         // Test Don't allow setup if CS is in service, but current RAT is already PS(e.g. LTE)
-        serviceStateChanged(TelephonyProtoEnums.NETWORK_TYPE_LTE,
+        serviceStateChanged(TelephonyManager.NETWORK_TYPE_LTE,
                 NetworkRegistrationInfo.REGISTRATION_STATE_NOT_REGISTERED_OR_SEARCHING,
                 NetworkRegistrationInfo.REGISTRATION_STATE_HOME,
                 NetworkRegistrationInfo.REGISTRATION_STATE_NOT_REGISTERED_OR_SEARCHING, null);
 
         verifyAllDataDisconnected();
 
-        // Test Allow if voice is in service if RAT is 2g/3g
-        serviceStateChanged(TelephonyProtoEnums.NETWORK_TYPE_1XRTT,
-                NetworkRegistrationInfo.REGISTRATION_STATE_NOT_REGISTERED_OR_SEARCHING,
+        // Test Allow if voice is in service if RAT is 2g/3g, use voice RAT to select data profile
+        ServiceState ss = createSS(TelephonyManager.NETWORK_TYPE_UNKNOWN /* data RAT */,
+                TelephonyManager.NETWORK_TYPE_1xRTT /* voice RAT */,
+                NetworkRegistrationInfo.REGISTRATION_STATE_NOT_REGISTERED_OR_SEARCHING ,
                 NetworkRegistrationInfo.REGISTRATION_STATE_HOME,
                 NetworkRegistrationInfo.REGISTRATION_STATE_NOT_REGISTERED_OR_SEARCHING, null);
+        doReturn(ss).when(mSST).getServiceState();
+        mDataNetworkControllerUT.obtainMessage(17/*EVENT_SERVICE_STATE_CHANGED*/).sendToTarget();
+        mDataNetworkControllerUT.removeNetworkRequest(request);
+        mDataNetworkControllerUT.addNetworkRequest(request);
+        processAllMessages();
 
         verifyConnectedNetworkHasCapabilities(NetworkCapabilities.NET_CAPABILITY_MMS);
     }
diff --git a/tests/telephonytests/src/com/android/internal/telephony/data/DataProfileManagerTest.java b/tests/telephonytests/src/com/android/internal/telephony/data/DataProfileManagerTest.java
index 7dda6c1..93dc75d 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/data/DataProfileManagerTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/data/DataProfileManagerTest.java
@@ -78,7 +78,13 @@
     private static final String GENERAL_PURPOSE_APN1 = "GP_APN1";
     private static final String IMS_APN = "IMS_APN";
     private static final String TETHERING_APN = "DUN_APN";
+    private static final String APN_SET_ID_1_APN = "APN_SET_ID_1_APN";
+    private static final String APN_SET_ID_1_TETHERING_APN = "APN_SET_ID_1_TETHERING_APN";
+    private static final String MATCH_ALL_APN_SET_ID_IMS_APN = "MATCH_ALL_APN_SET_ID_IMS_APN";
     private static final String PLMN = "330123";
+    private static final int DEFAULT_APN_SET_ID = Telephony.Carriers.NO_APN_SET_ID;
+    private static final int APN_SET_ID_1 = 1;
+    private static final int MATCH_ALL_APN_SET_ID = Telephony.Carriers.MATCH_ALL_APN_SET_ID;
 
     // Mocked classes
     private DataProfileManagerCallback mDataProfileManagerCallback;
@@ -159,7 +165,7 @@
                         TelephonyManager.NETWORK_TYPE_BITMASK_LTE
                                 | TelephonyManager.NETWORK_TYPE_BITMASK_NR, // network_type_bitmask
                         0,                      // lingering_network_type_bitmask
-                        0,                      // apn_set_id
+                        DEFAULT_APN_SET_ID,     // apn_set_id
                         -1,                     // carrier_id
                         -1,                     // skip_464xlat
                         0                       // always_on
@@ -193,7 +199,7 @@
                         "",                     // mnvo_match_data
                         TelephonyManager.NETWORK_TYPE_BITMASK_LTE, // network_type_bitmask
                         0,                      // lingering_network_type_bitmask
-                        0,                      // apn_set_id
+                        DEFAULT_APN_SET_ID,     // apn_set_id
                         -1,                     // carrier_id
                         -1,                     // skip_464xlat
                         0                       // always_on
@@ -227,7 +233,7 @@
                         "",                     // mnvo_match_data
                         TelephonyManager.NETWORK_TYPE_BITMASK_NR, // network_type_bitmask
                         0,                      // lingering_network_type_bitmask
-                        0,                      // apn_set_id
+                        DEFAULT_APN_SET_ID,     // apn_set_id
                         -1,                     // carrier_id
                         -1,                     // skip_464xlat
                         0                       // alwys_on
@@ -262,7 +268,7 @@
                         TelephonyManager.NETWORK_TYPE_BITMASK_LTE
                                 | TelephonyManager.NETWORK_TYPE_BITMASK_NR, // network_type_bitmask
                         0,                      // lingering_network_type_bitmask
-                        0,                      // apn_set_id
+                        DEFAULT_APN_SET_ID,     // apn_set_id
                         -1,                     // carrier_id
                         -1,                     // skip_464xlat
                         0                       // always_on
@@ -298,7 +304,112 @@
                         TelephonyManager.NETWORK_TYPE_BITMASK_LTE
                                 | TelephonyManager.NETWORK_TYPE_BITMASK_NR, // network_type_bitmask
                         0,                      // lingering_network_type_bitmask
-                        0,                      // apn_set_id
+                        DEFAULT_APN_SET_ID,     // apn_set_id
+                        -1,                     // carrier_id
+                        -1,                     // skip_464xlat
+                        0                       // always_on
+                },
+                new Object[]{
+                        6,                      // id
+                        PLMN,                   // numeric
+                        APN_SET_ID_1_APN,       // name
+                        APN_SET_ID_1_APN,       // apn
+                        "",                     // proxy
+                        "",                     // port
+                        "",                     // mmsc
+                        "",                     // mmsproxy
+                        "",                     // mmsport
+                        "",                     // user
+                        "",                     // password
+                        -1,                     // authtype
+                        "default,supl,mms,ia",  // types
+                        "IPV4V6",               // protocol
+                        "IPV4V6",               // roaming_protocol
+                        1,                      // carrier_enabled
+                        0,                      // profile_id
+                        1,                      // modem_cognitive
+                        0,                      // max_conns
+                        0,                      // wait_time
+                        0,                      // max_conns_time
+                        0,                      // mtu
+                        1280,                   // mtu_v4
+                        1280,                   // mtu_v6
+                        "",                     // mvno_type
+                        "",                     // mnvo_match_data
+                        TelephonyManager.NETWORK_TYPE_BITMASK_LTE
+                                | TelephonyManager.NETWORK_TYPE_BITMASK_NR, // network_type_bitmask
+                        0,                      // lingering_network_type_bitmask
+                        APN_SET_ID_1,           // apn_set_id
+                        -1,                     // carrier_id
+                        -1,                     // skip_464xlat
+                        0                       // always_on
+                },
+                new Object[]{
+                        7,                      // id
+                        PLMN,                   // numeric
+                        APN_SET_ID_1_TETHERING_APN, // name
+                        APN_SET_ID_1_TETHERING_APN, // apn
+                        "",                     // proxy
+                        "",                     // port
+                        "",                     // mmsc
+                        "",                     // mmsproxy
+                        "",                     // mmsport
+                        "",                     // user
+                        "",                     // password
+                        -1,                     // authtype
+                        "dun",                  // types
+                        "IPV4V6",               // protocol
+                        "IPV4V6",               // roaming_protocol
+                        1,                      // carrier_enabled
+                        0,                      // profile_id
+                        1,                      // modem_cognitive
+                        0,                      // max_conns
+                        0,                      // wait_time
+                        0,                      // max_conns_time
+                        0,                      // mtu
+                        1280,                   // mtu_v4
+                        1280,                   // mtu_v6
+                        "",                     // mvno_type
+                        "",                     // mnvo_match_data
+                        TelephonyManager.NETWORK_TYPE_BITMASK_LTE
+                                | TelephonyManager.NETWORK_TYPE_BITMASK_NR, // network_type_bitmask
+                        0,                      // lingering_network_type_bitmask
+                        APN_SET_ID_1,           // apn_set_id
+                        -1,                     // carrier_id
+                        -1,                     // skip_464xlat
+                        0                       // always_on
+                },
+                new Object[]{
+                        8,                      // id
+                        PLMN,                   // numeric
+                        MATCH_ALL_APN_SET_ID_IMS_APN, // name
+                        MATCH_ALL_APN_SET_ID_IMS_APN, // apn
+                        "",                     // proxy
+                        "",                     // port
+                        "",                     // mmsc
+                        "",                     // mmsproxy
+                        "",                     // mmsport
+                        "",                     // user
+                        "",                     // password
+                        -1,                     // authtype
+                        "ims",                  // types
+                        "IPV4V6",               // protocol
+                        "IPV4V6",               // roaming_protocol
+                        1,                      // carrier_enabled
+                        0,                      // profile_id
+                        1,                      // modem_cognitive
+                        0,                      // max_conns
+                        0,                      // wait_time
+                        0,                      // max_conns_time
+                        0,                      // mtu
+                        1280,                   // mtu_v4
+                        1280,                   // mtu_v6
+                        "",                     // mvno_type
+                        "",                     // mnvo_match_data
+                        TelephonyManager.NETWORK_TYPE_BITMASK_LTE
+                                | TelephonyManager.NETWORK_TYPE_BITMASK_NR, // network_type_bitmask
+                        0,                      // lingering_network_type_bitmask
+                        MATCH_ALL_APN_SET_ID,   // apn_set_id
                         -1,                     // carrier_id
                         -1,                     // skip_464xlat
                         0                       // always_on
@@ -404,6 +515,29 @@
         public void restoreApnSettings() {
             mDeletedApns.clear();
         }
+
+        public void setPreferredApn(String apnName) {
+            for (Object apnSetting : mAllApnSettings) {
+                if (apnName == ((Object[]) apnSetting)[3]) {
+                    mPreferredApnId = (int) ((Object[]) apnSetting)[0];
+                    mPreferredApnSet = (int) ((Object[]) apnSetting)[28];
+                    logd("mPreferredApnId=" + mPreferredApnId + " ,mPreferredApnSet="
+                            + mPreferredApnSet);
+                    break;
+                }
+            }
+        }
+
+        public int getCountApnSpecifyType(String type) {
+            int count = 0;
+            for (Object apnSetting : mAllApnSettings) {
+                String apnTypes = (String) ((Object[]) apnSetting)[12];
+                if (apnTypes.contains(type)) {
+                    count++;
+                }
+            }
+            return count;
+        }
     }
 
     /**
@@ -718,6 +852,7 @@
                 tnr, TelephonyManager.NETWORK_TYPE_LTE, false);
         assertThat(dataProfile).isNull();
 
+        // expect default EIMS when SIM absent
         tnr = new TelephonyNetworkRequest(
                 new NetworkRequest.Builder()
                         .addCapability(NetworkCapabilities.NET_CAPABILITY_EIMS)
@@ -726,13 +861,14 @@
                 tnr, TelephonyManager.NETWORK_TYPE_LTE, false);
         assertThat(dataProfile.getApnSetting().getApnName()).isEqualTo("sos");
 
+        // expect no default IMS when SIM absent
         tnr = new TelephonyNetworkRequest(
                 new NetworkRequest.Builder()
                         .addCapability(NetworkCapabilities.NET_CAPABILITY_IMS)
                         .build(), mPhone);
         dataProfile = mDataProfileManagerUT.getDataProfileForNetworkRequest(
                 tnr, TelephonyManager.NETWORK_TYPE_LTE, false);
-        assertThat(dataProfile.getApnSetting().getApnName()).isEqualTo("ims");
+        assertThat(dataProfile).isEqualTo(null);
     }
 
     @Test
@@ -938,10 +1074,22 @@
         mDataProfileManagerUT.obtainMessage(2 /*EVENT_APN_DATABASE_CHANGED*/).sendToTarget();
         processAllMessages();
 
-        // preferred APN should set to be the prev preferred
+        // preferred APN should set to be the last data profile that succeeded for internet setup
         assertThat(mDataProfileManagerUT.isAnyPreferredDataProfileExisting()).isTrue();
         assertThat(mDataProfileManagerUT.isDataProfilePreferred(dataProfile)).isTrue();
 
+        // no active internet, expect no preferred APN after reset
+        mDataNetworkControllerCallback.onInternetDataNetworkDisconnected();
+        mPreferredApnId = -1;
+        mDataProfileManagerUT.obtainMessage(2 /*EVENT_APN_DATABASE_CHANGED*/).sendToTarget();
+        processAllMessages();
+
+        assertThat(mDataProfileManagerUT.isAnyPreferredDataProfileExisting()).isFalse();
+        assertThat(mDataProfileManagerUT.isDataProfilePreferred(dataProfile)).isFalse();
+
+        // setup internet again
+        mDataNetworkControllerCallback.onInternetDataNetworkConnected(List.of(dataProfile));
+        processAllMessages();
         //APN reset and removed GENERAL_PURPOSE_APN(as if user created) from APN DB
         mPreferredApnId = -1;
         mApnSettingContentProvider.removeApnByApnId(1);
@@ -1023,12 +1171,13 @@
     @Test
     public void testNoDefaultIms() throws Exception {
         List<DataProfile> dataProfiles = getAllDataProfiles();
+        int countIms =  mApnSettingContentProvider.getCountApnSpecifyType("ims");
 
         // Since the database already had IMS, there should not be default IMS created in the
         // database.
         assertThat(dataProfiles.stream()
                 .filter(dp -> dp.canSatisfy(NetworkCapabilities.NET_CAPABILITY_IMS))
-                .collect(Collectors.toList())).hasSize(1);
+                .collect(Collectors.toList())).hasSize(countIms);
     }
 
     @Test
@@ -1064,9 +1213,192 @@
                         .setNetworkTypeBitmask((int) (TelephonyManager.NETWORK_TYPE_BITMASK_LTE
                                 | TelephonyManager.NETWORK_TYPE_BITMASK_NR))
                         .setMvnoMatchData("")
+                        .setApnSetId(DEFAULT_APN_SET_ID)
                         .build())
                 .build();
 
         assertThat(mDataProfileManagerUT.isDataProfileCompatible(dataProfile1)).isTrue();
     }
+
+    @Test
+    public void testDataProfileCompatibility_FilteringWithPreferredApnSetIdAsDefault() {
+        mApnSettingContentProvider.setPreferredApn(GENERAL_PURPOSE_APN);
+        mSimInserted = true;
+        mDataProfileManagerUT.obtainMessage(2 /*EVENT_APN_DATABASE_CHANGED*/).sendToTarget();
+        processAllMessages();
+
+        // Test DataProfile's apn_set_id is default so it match with current preferred apn_set_id.
+        DataProfile dataProfile1 = new DataProfile.Builder()
+                .setApnSetting(new ApnSetting.Builder()
+                        .setEntryName(TETHERING_APN)
+                        .setOperatorNumeric(PLMN)
+                        .setApnName(TETHERING_APN)
+                        .setProxyAddress("")
+                        .setMmsProxyAddress("")
+                        .setApnTypeBitmask(ApnSetting.TYPE_DUN)
+                        .setUser("")
+                        .setPassword("")
+                        .setAuthType(ApnSetting.AUTH_TYPE_UNKNOWN)
+                        .setProtocol(ApnSetting.PROTOCOL_IPV4V6)
+                        .setRoamingProtocol(ApnSetting.PROTOCOL_IPV4V6)
+                        .setCarrierEnabled(true)
+                        .setProfileId(2)
+                        .setPersistent(true)
+                        .setMtuV4(0)
+                        .setMtuV6(0)
+                        .setNetworkTypeBitmask((int) (TelephonyManager.NETWORK_TYPE_BITMASK_NR))
+                        .setMvnoMatchData("")
+                        .setApnSetId(DEFAULT_APN_SET_ID)
+                        .build())
+                .build();
+
+        assertThat(mDataProfileManagerUT.isDataProfileCompatible(dataProfile1)).isTrue();
+
+        // Test DataProfile's apn_set_id is specified(1) so it not match with current
+        // preferred apn_set_id.
+        DataProfile dataProfile2 = new DataProfile.Builder()
+                .setApnSetting(new ApnSetting.Builder()
+                        .setEntryName(APN_SET_ID_1_TETHERING_APN)
+                        .setOperatorNumeric(PLMN)
+                        .setApnName(APN_SET_ID_1_TETHERING_APN)
+                        .setProxyAddress("")
+                        .setMmsProxyAddress("")
+                        .setApnTypeBitmask(ApnSetting.TYPE_DUN)
+                        .setUser("")
+                        .setPassword("")
+                        .setAuthType(ApnSetting.AUTH_TYPE_UNKNOWN)
+                        .setProtocol(ApnSetting.PROTOCOL_IPV4V6)
+                        .setRoamingProtocol(ApnSetting.PROTOCOL_IPV4V6)
+                        .setCarrierEnabled(true)
+                        .setPersistent(true)
+                        .setMtuV4(1280)
+                        .setMtuV6(1280)
+                        .setNetworkTypeBitmask((int) (TelephonyManager.NETWORK_TYPE_BITMASK_LTE
+                                | TelephonyManager.NETWORK_TYPE_BITMASK_NR))
+                        .setMvnoMatchData("")
+                        .setApnSetId(APN_SET_ID_1)
+                        .build())
+                .build();
+
+        assertThat(mDataProfileManagerUT.isDataProfileCompatible(dataProfile2)).isFalse();
+
+        // Test DataProfile has Telephony.Carriers.MATCH_ALL_APN_SET_ID so it matches any preferred
+        // apn_set_id.
+        DataProfile dataProfile3 = new DataProfile.Builder()
+                .setApnSetting(new ApnSetting.Builder()
+                        .setEntryName(MATCH_ALL_APN_SET_ID_IMS_APN)
+                        .setOperatorNumeric(PLMN)
+                        .setApnName(MATCH_ALL_APN_SET_ID_IMS_APN)
+                        .setProxyAddress("")
+                        .setMmsProxyAddress("")
+                        .setApnTypeBitmask(ApnSetting.TYPE_IMS)
+                        .setUser("")
+                        .setPassword("")
+                        .setAuthType(ApnSetting.AUTH_TYPE_UNKNOWN)
+                        .setProtocol(ApnSetting.PROTOCOL_IPV4V6)
+                        .setRoamingProtocol(ApnSetting.PROTOCOL_IPV4V6)
+                        .setCarrierEnabled(true)
+                        .setPersistent(true)
+                        .setMtuV4(1280)
+                        .setMtuV6(1280)
+                        .setNetworkTypeBitmask((int) (TelephonyManager.NETWORK_TYPE_BITMASK_LTE
+                                | TelephonyManager.NETWORK_TYPE_BITMASK_NR))
+                        .setMvnoMatchData("")
+                        .setApnSetId(MATCH_ALL_APN_SET_ID)
+                        .build())
+                .build();
+
+        assertThat(mDataProfileManagerUT.isDataProfileCompatible(dataProfile3)).isTrue();
+    }
+
+    @Test
+    public void testDataProfileCompatibility_FilteringWithPreferredApnSetIdAs1() {
+        mApnSettingContentProvider.setPreferredApn(APN_SET_ID_1_APN);
+        mSimInserted = true;
+        mDataProfileManagerUT.obtainMessage(2 /*EVENT_APN_DATABASE_CHANGED*/).sendToTarget();
+        processAllMessages();
+
+        // Test DataProfile's apn_set_id is same as preferred apn_set_id.
+        DataProfile dataProfile1 = new DataProfile.Builder()
+                .setApnSetting(new ApnSetting.Builder()
+                        .setEntryName(APN_SET_ID_1_TETHERING_APN)
+                        .setOperatorNumeric(PLMN)
+                        .setApnName(APN_SET_ID_1_TETHERING_APN)
+                        .setProxyAddress("")
+                        .setMmsProxyAddress("")
+                        .setApnTypeBitmask(ApnSetting.TYPE_DUN)
+                        .setUser("")
+                        .setPassword("")
+                        .setAuthType(ApnSetting.AUTH_TYPE_UNKNOWN)
+                        .setProtocol(ApnSetting.PROTOCOL_IPV4V6)
+                        .setRoamingProtocol(ApnSetting.PROTOCOL_IPV4V6)
+                        .setCarrierEnabled(true)
+                        .setPersistent(true)
+                        .setMtuV4(1280)
+                        .setMtuV6(1280)
+                        .setNetworkTypeBitmask((int) (TelephonyManager.NETWORK_TYPE_BITMASK_LTE
+                                | TelephonyManager.NETWORK_TYPE_BITMASK_NR))
+                        .setMvnoMatchData("")
+                        .setApnSetId(APN_SET_ID_1)
+                        .build())
+                .build();
+
+        assertThat(mDataProfileManagerUT.isDataProfileCompatible(dataProfile1)).isTrue();
+
+        // Test DataProfile's apn_set_id is default. so it not match with current preferred
+        // apn_set_id(1).
+        DataProfile dataProfile2 = new DataProfile.Builder()
+                .setApnSetting(new ApnSetting.Builder()
+                        .setEntryName(TETHERING_APN)
+                        .setOperatorNumeric(PLMN)
+                        .setApnName(TETHERING_APN)
+                        .setProxyAddress("")
+                        .setMmsProxyAddress("")
+                        .setApnTypeBitmask(ApnSetting.TYPE_DUN)
+                        .setUser("")
+                        .setPassword("")
+                        .setAuthType(ApnSetting.AUTH_TYPE_UNKNOWN)
+                        .setProtocol(ApnSetting.PROTOCOL_IPV4V6)
+                        .setRoamingProtocol(ApnSetting.PROTOCOL_IPV4V6)
+                        .setCarrierEnabled(true)
+                        .setProfileId(2)
+                        .setPersistent(true)
+                        .setMtuV4(0)
+                        .setMtuV6(0)
+                        .setNetworkTypeBitmask((int) (TelephonyManager.NETWORK_TYPE_BITMASK_NR))
+                        .setMvnoMatchData("")
+                        .setApnSetId(DEFAULT_APN_SET_ID)
+                        .build())
+                .build();
+
+        assertThat(mDataProfileManagerUT.isDataProfileCompatible(dataProfile2)).isFalse();
+
+        // Test DataProfile has Telephony.Carriers.MATCH_ALL_APN_SET_ID so it matches any preferred
+        // apn_set_id.
+        DataProfile dataProfile3 = new DataProfile.Builder()
+                .setApnSetting(new ApnSetting.Builder()
+                        .setEntryName(MATCH_ALL_APN_SET_ID_IMS_APN)
+                        .setOperatorNumeric(PLMN)
+                        .setApnName(MATCH_ALL_APN_SET_ID_IMS_APN)
+                        .setProxyAddress("")
+                        .setMmsProxyAddress("")
+                        .setApnTypeBitmask(ApnSetting.TYPE_IMS)
+                        .setUser("")
+                        .setPassword("")
+                        .setAuthType(ApnSetting.AUTH_TYPE_UNKNOWN)
+                        .setProtocol(ApnSetting.PROTOCOL_IPV4V6)
+                        .setRoamingProtocol(ApnSetting.PROTOCOL_IPV4V6)
+                        .setCarrierEnabled(true)
+                        .setPersistent(true)
+                        .setMtuV4(1280)
+                        .setMtuV6(1280)
+                        .setNetworkTypeBitmask((int) (TelephonyManager.NETWORK_TYPE_BITMASK_LTE
+                                | TelephonyManager.NETWORK_TYPE_BITMASK_NR))
+                        .setMvnoMatchData("")
+                        .setApnSetId(MATCH_ALL_APN_SET_ID)
+                        .build())
+                .build();
+
+        assertThat(mDataProfileManagerUT.isDataProfileCompatible(dataProfile3)).isTrue();
+    }
 }
diff --git a/tests/telephonytests/src/com/android/internal/telephony/data/DataRetryManagerTest.java b/tests/telephonytests/src/com/android/internal/telephony/data/DataRetryManagerTest.java
index 348d96f..769a920 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/data/DataRetryManagerTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/data/DataRetryManagerTest.java
@@ -16,6 +16,8 @@
 
 package com.android.internal.telephony.data;
 
+import static com.android.internal.telephony.data.DataRetryManager.DataHandoverRetryEntry;
+import static com.android.internal.telephony.data.DataRetryManager.DataRetryEntry;
 import static com.android.internal.telephony.data.DataRetryManager.DataSetupRetryEntry;
 
 import static com.google.common.truth.Truth.assertThat;
@@ -25,6 +27,7 @@
 import static org.mockito.Mockito.doAnswer;
 import static org.mockito.Mockito.doReturn;
 import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
 
 import android.net.NetworkCapabilities;
@@ -55,6 +58,7 @@
 import org.mockito.ArgumentCaptor;
 import org.mockito.Mockito;
 
+import java.lang.reflect.Field;
 import java.util.Collections;
 import java.util.List;
 
@@ -328,15 +332,38 @@
     }
 
     @Test
-    public void testDataSetupUnthrottling() {
+    public void testDataSetupUnthrottling() throws Exception {
         testDataSetupRetryNetworkSuggestedNeverRetry();
         Mockito.clearInvocations(mDataRetryManagerCallbackMock);
+        DataNetworkController.NetworkRequestList mockNrl = Mockito.mock(
+                DataNetworkController.NetworkRequestList.class);
+        Field field = DataRetryManager.class.getDeclaredField("mDataRetryEntries");
+        field.setAccessible(true);
+        List<DataRetryEntry> mDataRetryEntries =
+                (List<DataRetryEntry>) field.get(mDataRetryManagerUT);
 
+        // schedule 2 setup retries
+        DataSetupRetryEntry scheduledRetry1 = new DataSetupRetryEntry.Builder<>()
+                .setDataProfile(mDataProfile3)
+                .setNetworkRequestList(mockNrl)
+                .setTransport(AccessNetworkConstants.TRANSPORT_TYPE_WWAN)
+                .setSetupRetryType(1)
+                .build();
+        DataSetupRetryEntry scheduledRetry2 = new DataSetupRetryEntry.Builder<>()
+                .setNetworkRequestList(mockNrl)
+                .setDataProfile(mDataProfile3)
+                .setTransport(AccessNetworkConstants.TRANSPORT_TYPE_WLAN)
+                .setSetupRetryType(1)
+                .build();
+        mDataRetryEntries.addAll(List.of(scheduledRetry1, scheduledRetry2));
+
+        // unthrottle the data profile, expect previous retries of the same transport is cancelled
         mDataRetryManagerUT.obtainMessage(6/*EVENT_DATA_PROFILE_UNTHROTTLED*/,
                 new AsyncResult(AccessNetworkConstants.TRANSPORT_TYPE_WWAN, mDataProfile3, null))
                 .sendToTarget();
         processAllMessages();
 
+        // check unthrottle
         ArgumentCaptor<List<ThrottleStatus>> throttleStatusCaptor =
                 ArgumentCaptor.forClass(List.class);
         verify(mDataRetryManagerCallbackMock).onThrottleStatusChanged(
@@ -358,6 +385,10 @@
         assertThat(entry.dataProfile).isEqualTo(mDataProfile3);
         assertThat(entry.retryDelayMillis).isEqualTo(0);
         assertThat(entry.transport).isEqualTo(AccessNetworkConstants.TRANSPORT_TYPE_WWAN);
+
+        // check mDataProfile3-WWAN retry is cancelled, but not the WLAN
+        assertThat(scheduledRetry1.getState()).isEqualTo(DataRetryEntry.RETRY_STATE_CANCELLED);
+        assertThat(scheduledRetry2.getState()).isEqualTo(DataRetryEntry.RETRY_STATE_NOT_RETRIED);
     }
 
     @Test
@@ -396,6 +427,66 @@
     }
 
     @Test
+    public void testCancellingRetries() throws Exception {
+        DataNetworkController.NetworkRequestList mockNrl = Mockito.mock(
+                DataNetworkController.NetworkRequestList.class);
+
+        // Test: setup retry
+        DataRetryEntry retry = new DataSetupRetryEntry.Builder<>()
+                .setSetupRetryType(1)
+                .setNetworkRequestList(mockNrl)
+                .setTransport(1)
+                .build();
+        retry.setState(DataRetryEntry.RETRY_STATE_CANCELLED);
+
+        mDataRetryManagerUT.obtainMessage(3/*EVENT_DATA_SETUP_RETRY*/, retry).sendToTarget();
+        processAllMessages();
+        verify(mDataRetryManagerCallbackMock, never()).onDataNetworkSetupRetry(any());
+
+        mDataRetryManagerUT.obtainMessage(3/*EVENT_DATA_SETUP_RETRY*/, null).sendToTarget();
+        processAllMessages();
+        verify(mDataRetryManagerCallbackMock, never()).onDataNetworkSetupRetry(any());
+
+        retry.setState(DataRetryEntry.RETRY_STATE_NOT_RETRIED);
+        mDataRetryManagerUT.obtainMessage(3/*EVENT_DATA_SETUP_RETRY*/, retry).sendToTarget();
+        processAllMessages();
+        verify(mDataRetryManagerCallbackMock, times(1)).onDataNetworkSetupRetry(any());
+
+        // Test: handover retry
+        retry = new DataHandoverRetryEntry.Builder<>().build();
+        retry.setState(DataRetryEntry.RETRY_STATE_CANCELLED);
+        mDataRetryManagerUT.obtainMessage(4/*EVENT_DATA_HANDOVER_RETRY*/, retry).sendToTarget();
+        processAllMessages();
+        verify(mDataRetryManagerCallbackMock, never()).onDataNetworkHandoverRetry(any());
+
+        mDataRetryManagerUT.obtainMessage(4/*EVENT_DATA_HANDOVER_RETRY*/, null).sendToTarget();
+        processAllMessages();
+        verify(mDataRetryManagerCallbackMock, never()).onDataNetworkHandoverRetry(any());
+
+        retry.setState(DataRetryEntry.RETRY_STATE_NOT_RETRIED);
+        mDataRetryManagerUT.obtainMessage(4/*EVENT_DATA_HANDOVER_RETRY*/, retry).sendToTarget();
+        processAllMessages();
+        verify(mDataRetryManagerCallbackMock, times(1))
+                .onDataNetworkHandoverRetry(any());
+
+        // Test: cancelPendingHandoverRetry
+        DataNetwork mockDn = Mockito.mock(DataNetwork.class);
+        Field field = DataRetryManager.class.getDeclaredField("mDataRetryEntries");
+        field.setAccessible(true);
+        List<DataRetryEntry> mDataRetryEntries =
+                (List<DataRetryEntry>) field.get(mDataRetryManagerUT);
+        retry = new DataHandoverRetryEntry.Builder<>()
+                .setDataNetwork(mockDn)
+                .build();
+        mDataRetryEntries.add(retry);
+        mDataRetryManagerUT.cancelPendingHandoverRetry(mockDn);
+        processAllMessages();
+
+        assertThat(mDataRetryManagerUT.isAnyHandoverRetryScheduled(mockDn)).isFalse();
+        assertThat(retry.getState()).isEqualTo(DataRetryEntry.RETRY_STATE_CANCELLED);
+    }
+
+    @Test
     public void testDataSetupRetryPermanentFailure() {
         DataSetupRetryRule retryRule = new DataSetupRetryRule(
                 "permanent_fail_causes=8|27|28|29|30|32|33|35|50|51|111|-5|-6|65537|65538|-3|65543|"
@@ -598,7 +689,7 @@
             assertThat(entry.networkRequestList).isEqualTo(networkRequestList);
             assertThat(entry.appliedDataRetryRule).isEqualTo(retryRule3);
 
-            entry.setState(DataRetryManager.DataRetryEntry.RETRY_STATE_FAILED);
+            entry.setState(DataRetryEntry.RETRY_STATE_FAILED);
         }
 
         // The last fail should not trigger any retry.
diff --git a/tests/telephonytests/src/com/android/internal/telephony/data/QosCallbackTrackerTest.java b/tests/telephonytests/src/com/android/internal/telephony/data/QosCallbackTrackerTest.java
index 00bca4d..7856564 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/data/QosCallbackTrackerTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/data/QosCallbackTrackerTest.java
@@ -51,7 +51,6 @@
 import java.net.InetAddress;
 import java.net.InetSocketAddress;
 import java.util.ArrayList;
-import java.util.Arrays;
 
 @RunWith(AndroidTestingRunner.class)
 @TestableLooper.RunWithLooper
@@ -76,7 +75,7 @@
                 final int startPort, final int endPort) {
             return startPort <= mLocalAddress.getPort()
                     && endPort >= mLocalAddress.getPort()
-                    && mLocalAddress.getAddress().equals(address);
+                    && (address.isAnyLocalAddress() || mLocalAddress.getAddress().equals(address));
         }
 
         public boolean matchesRemoteAddress(final @NonNull InetAddress address,
@@ -84,7 +83,7 @@
             return mRemoteAddress != null
                     && startPort <= mRemoteAddress.getPort()
                     && endPort >= mRemoteAddress.getPort()
-                    && mRemoteAddress.getAddress().equals(address);
+                    && (address.isAnyLocalAddress() || mRemoteAddress.getAddress().equals(address));
         }
     }
 
@@ -132,22 +131,32 @@
 
     public static QosBearerFilter createIpv4QosFilter(String localAddress,
             QosBearerFilter.PortRange localPort, int precedence) {
+        ArrayList<LinkAddress> localAddresses = new ArrayList<>();
+        if (localAddress != null) {
+            localAddresses.add(
+                    new LinkAddress(InetAddresses.parseNumericAddress(localAddress), 32));
+        }
         return new QosBearerFilter(
-                Arrays.asList(
-                        new LinkAddress(InetAddresses.parseNumericAddress(localAddress), 32)),
-                new ArrayList<>(), localPort, null, QosBearerFilter.QOS_PROTOCOL_TCP,
-                7, 987, 678, QosBearerFilter.QOS_FILTER_DIRECTION_BIDIRECTIONAL, precedence);
+                localAddresses, new ArrayList<>(), localPort, null,
+                QosBearerFilter.QOS_PROTOCOL_TCP, 7, 987, 678,
+                QosBearerFilter.QOS_FILTER_DIRECTION_BIDIRECTIONAL, precedence);
     }
 
     private static QosBearerFilter createIpv4QosFilter(String localAddress, String remoteAddress,
             QosBearerFilter.PortRange localPort, QosBearerFilter.PortRange remotePort,
             int precedence) {
+        ArrayList<LinkAddress> localAddresses = new ArrayList<>();
+        if (localAddress != null) {
+            localAddresses.add(
+                    new LinkAddress(InetAddresses.parseNumericAddress(localAddress), 32));
+        }
+        ArrayList<LinkAddress> remoteAddresses = new ArrayList<>();
+        if (localAddress != null) {
+            remoteAddresses.add(
+                    new LinkAddress(InetAddresses.parseNumericAddress(remoteAddress), 32));
+        }
         return new QosBearerFilter(
-                Arrays.asList(
-                        new LinkAddress(InetAddresses.parseNumericAddress(localAddress), 32)),
-                Arrays.asList(
-                        new LinkAddress(InetAddresses.parseNumericAddress(remoteAddress), 32)),
-                localPort, remotePort,
+                localAddresses, remoteAddresses, localPort, remotePort,
                 QosBearerFilter.QOS_PROTOCOL_TCP, 7, 987, 678,
                 QosBearerFilter.QOS_FILTER_DIRECTION_BIDIRECTIONAL, precedence);
     }
@@ -510,6 +519,37 @@
 
     @Test
     @SmallTest
+    public void testQosSessionFilterPortRangeWithoutAddress() throws Exception {
+        // QosBearerFilter including remote port range without remote address
+        ArrayList<QosBearerFilter> qosFilters1 = new ArrayList<>();
+        qosFilters1.add(createIpv4QosFilter(null, null, null,
+                new QosBearerFilter.PortRange(3200, 3220), 45));
+
+        ArrayList<QosBearerSession> qosSessions = new ArrayList<>();
+        qosSessions.add(new QosBearerSession(1234, createEpsQos(5, 6, 7, 8), qosFilters1));
+
+        mQosCallbackTracker.updateSessions(qosSessions);
+
+        // Add filter after updateSessions
+        Filter filter = new Filter(new InetSocketAddress(
+                InetAddresses.parseNumericAddress("122.22.22.22"), 1357),
+                new InetSocketAddress(InetAddresses.parseNumericAddress("177.77.77.77"), 3202));
+        mQosCallbackTracker.addFilter(1, filter);
+        processAllMessages();
+
+        verify(mNetworkAgent, times(1)).notifyQosSessionAvailable(eq(1),
+                eq(1234), any(EpsBearerQosSessionAttributes.class));
+
+        // Remove the matching QosBearerFilter
+        qosSessions.remove(0);
+        mQosCallbackTracker.updateSessions(qosSessions);
+        processAllMessages();
+
+        verify(mNetworkAgent, times(1)).notifyQosSessionLost(eq(1), eq(1234), eq(1));
+    }
+
+    @Test
+    @SmallTest
     public void testQosMetrics() throws Exception {
         final int callbackId = 1;
         final int slotId = mPhone.getPhoneId();
diff --git a/tests/telephonytests/src/com/android/internal/telephony/imsphone/ImsPhoneCallTrackerTest.java b/tests/telephonytests/src/com/android/internal/telephony/imsphone/ImsPhoneCallTrackerTest.java
index ec2209d..1a94727 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/imsphone/ImsPhoneCallTrackerTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/imsphone/ImsPhoneCallTrackerTest.java
@@ -1876,11 +1876,14 @@
         assertEquals(1, mCTUT.getConnections().size());
         assertNotNull(mCTUT.getPendingMO());
         assertEquals(Call.State.DIALING, mCTUT.mForegroundCall.getState());
+        assertEquals(PhoneConstants.State.OFFHOOK, mCTUT.getState());
 
         mCTUT.cleanupAndRemoveConnection(conn);
         assertEquals(0, mCTUT.getConnections().size());
         assertNull(mCTUT.getPendingMO());
         assertEquals(Call.State.IDLE, mCTUT.mForegroundCall.getState());
+
+        assertEquals(PhoneConstants.State.IDLE, mCTUT.getState());
     }
 
     @Test
diff --git a/tests/telephonytests/src/com/android/internal/telephony/metrics/PersistAtomsStorageTest.java b/tests/telephonytests/src/com/android/internal/telephony/metrics/PersistAtomsStorageTest.java
index ab8ee33..e46b822 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/metrics/PersistAtomsStorageTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/metrics/PersistAtomsStorageTest.java
@@ -31,9 +31,6 @@
 import static com.android.internal.telephony.TelephonyStatsLog.VOICE_CALL_SESSION__BEARER_AT_END__CALL_BEARER_IMS;
 import static com.android.internal.telephony.TelephonyStatsLog.VOICE_CALL_SESSION__DIRECTION__CALL_DIRECTION_MO;
 import static com.android.internal.telephony.TelephonyStatsLog.VOICE_CALL_SESSION__DIRECTION__CALL_DIRECTION_MT;
-import static com.android.internal.telephony.TelephonyStatsLog.VOICE_CALL_SESSION__SETUP_DURATION__CALL_SETUP_DURATION_EXTREMELY_FAST;
-import static com.android.internal.telephony.TelephonyStatsLog.VOICE_CALL_SESSION__SETUP_DURATION__CALL_SETUP_DURATION_VERY_FAST;
-import static com.android.internal.telephony.TelephonyStatsLog.VOICE_CALL_SESSION__SETUP_DURATION__CALL_SETUP_DURATION_VERY_SLOW;
 
 import static org.junit.Assert.assertArrayEquals;
 import static org.junit.Assert.assertEquals;
@@ -233,8 +230,6 @@
         mCall1Proto.bearerAtStart = VOICE_CALL_SESSION__BEARER_AT_END__CALL_BEARER_IMS;
         mCall1Proto.bearerAtEnd = VOICE_CALL_SESSION__BEARER_AT_END__CALL_BEARER_CS;
         mCall1Proto.direction = VOICE_CALL_SESSION__DIRECTION__CALL_DIRECTION_MO;
-        mCall1Proto.setupDuration =
-                VOICE_CALL_SESSION__SETUP_DURATION__CALL_SETUP_DURATION_VERY_FAST;
         mCall1Proto.setupFailed = false;
         mCall1Proto.disconnectReasonCode = DisconnectCause.LOCAL;
         mCall1Proto.disconnectExtraCode = 0;
@@ -263,8 +258,6 @@
         mCall2Proto.bearerAtStart = VOICE_CALL_SESSION__BEARER_AT_END__CALL_BEARER_IMS;
         mCall2Proto.bearerAtEnd = VOICE_CALL_SESSION__BEARER_AT_END__CALL_BEARER_IMS;
         mCall2Proto.direction = VOICE_CALL_SESSION__DIRECTION__CALL_DIRECTION_MT;
-        mCall2Proto.setupDuration =
-                VOICE_CALL_SESSION__SETUP_DURATION__CALL_SETUP_DURATION_VERY_FAST;
         mCall2Proto.setupFailed = false;
         mCall2Proto.disconnectReasonCode = ImsReasonInfo.CODE_USER_TERMINATED_BY_REMOTE;
         mCall2Proto.disconnectExtraCode = 0;
@@ -292,8 +285,6 @@
         mCall3Proto.bearerAtStart = VOICE_CALL_SESSION__BEARER_AT_END__CALL_BEARER_IMS;
         mCall3Proto.bearerAtEnd = VOICE_CALL_SESSION__BEARER_AT_END__CALL_BEARER_IMS;
         mCall3Proto.direction = VOICE_CALL_SESSION__DIRECTION__CALL_DIRECTION_MT;
-        mCall3Proto.setupDuration =
-                VOICE_CALL_SESSION__SETUP_DURATION__CALL_SETUP_DURATION_EXTREMELY_FAST;
         mCall3Proto.setupFailed = false;
         mCall3Proto.disconnectReasonCode = ImsReasonInfo.CODE_USER_TERMINATED;
         mCall3Proto.disconnectExtraCode = 0;
@@ -320,8 +311,6 @@
         mCall4Proto.bearerAtStart = VOICE_CALL_SESSION__BEARER_AT_END__CALL_BEARER_CS;
         mCall4Proto.bearerAtEnd = VOICE_CALL_SESSION__BEARER_AT_END__CALL_BEARER_CS;
         mCall4Proto.direction = VOICE_CALL_SESSION__DIRECTION__CALL_DIRECTION_MO;
-        mCall4Proto.setupDuration =
-                VOICE_CALL_SESSION__SETUP_DURATION__CALL_SETUP_DURATION_VERY_SLOW;
         mCall4Proto.setupFailed = true;
         mCall4Proto.disconnectReasonCode = DisconnectCause.NORMAL;
         mCall4Proto.disconnectExtraCode = 0;
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 fd6cbff..a1a7866 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/metrics/VoiceCallSessionStatsTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/metrics/VoiceCallSessionStatsTest.java
@@ -30,10 +30,6 @@
 import static com.android.internal.telephony.TelephonyStatsLog.VOICE_CALL_SESSION__MAIN_CODEC_QUALITY__CODEC_QUALITY_NARROWBAND;
 import static com.android.internal.telephony.TelephonyStatsLog.VOICE_CALL_SESSION__MAIN_CODEC_QUALITY__CODEC_QUALITY_SUPER_WIDEBAND;
 import static com.android.internal.telephony.TelephonyStatsLog.VOICE_CALL_SESSION__MAIN_CODEC_QUALITY__CODEC_QUALITY_UNKNOWN;
-import static com.android.internal.telephony.TelephonyStatsLog.VOICE_CALL_SESSION__SETUP_DURATION__CALL_SETUP_DURATION_EXTREMELY_FAST;
-import static com.android.internal.telephony.TelephonyStatsLog.VOICE_CALL_SESSION__SETUP_DURATION__CALL_SETUP_DURATION_ULTRA_FAST;
-import static com.android.internal.telephony.TelephonyStatsLog.VOICE_CALL_SESSION__SETUP_DURATION__CALL_SETUP_DURATION_UNKNOWN;
-import static com.android.internal.telephony.TelephonyStatsLog.VOICE_CALL_SESSION__SETUP_DURATION__CALL_SETUP_DURATION_VERY_SLOW;
 
 import static com.google.common.truth.Truth.assertThat;
 import static com.google.common.truth.Truth.assertWithMessage;
@@ -81,6 +77,7 @@
 
 import org.junit.After;
 import org.junit.Before;
+import org.junit.Ignore;
 import org.junit.Test;
 import org.mockito.ArgumentCaptor;
 
@@ -228,8 +225,6 @@
                         VOICE_CALL_SESSION__DIRECTION__CALL_DIRECTION_MO,
                         TelephonyManager.NETWORK_TYPE_LTE,
                         ImsReasonInfo.CODE_REMOTE_CALL_DECLINE);
-        expectedCall.setupDuration =
-                VOICE_CALL_SESSION__SETUP_DURATION__CALL_SETUP_DURATION_EXTREMELY_FAST;
         expectedCall.setupDurationMillis = 200;
         expectedCall.setupFailed = true;
         expectedCall.ratAtConnected = TelephonyManager.NETWORK_TYPE_UNKNOWN;
@@ -365,8 +360,6 @@
                         VOICE_CALL_SESSION__DIRECTION__CALL_DIRECTION_MO,
                         TelephonyManager.NETWORK_TYPE_LTE,
                         ImsReasonInfo.CODE_USER_TERMINATED_BY_REMOTE);
-        expectedCall.setupDuration =
-                VOICE_CALL_SESSION__SETUP_DURATION__CALL_SETUP_DURATION_EXTREMELY_FAST;
         expectedCall.setupDurationMillis = 200;
         expectedCall.setupFailed = false;
         expectedCall.codecBitmask = 1L << AudioCodec.AUDIO_CODEC_EVS_SWB;
@@ -520,8 +513,6 @@
                         VOICE_CALL_SESSION__DIRECTION__CALL_DIRECTION_MT,
                         TelephonyManager.NETWORK_TYPE_LTE,
                         ImsReasonInfo.CODE_USER_TERMINATED);
-        expectedCall.setupDuration =
-                VOICE_CALL_SESSION__SETUP_DURATION__CALL_SETUP_DURATION_EXTREMELY_FAST;
         expectedCall.setupDurationMillis = 80;
         expectedCall.setupFailed = false;
         expectedCall.codecBitmask = 1L << AudioCodec.AUDIO_CODEC_AMR;
@@ -792,8 +783,6 @@
                         VOICE_CALL_SESSION__DIRECTION__CALL_DIRECTION_MT,
                         TelephonyManager.NETWORK_TYPE_LTE,
                         ImsReasonInfo.CODE_USER_TERMINATED);
-        expectedCall.setupDuration =
-                VOICE_CALL_SESSION__SETUP_DURATION__CALL_SETUP_DURATION_EXTREMELY_FAST;
         expectedCall.setupDurationMillis = 80;
         expectedCall.setupFailed = false;
         expectedCall.codecBitmask =
@@ -846,8 +835,6 @@
                         VOICE_CALL_SESSION__DIRECTION__CALL_DIRECTION_MT,
                         TelephonyManager.NETWORK_TYPE_LTE,
                         ImsReasonInfo.CODE_USER_TERMINATED);
-        expectedCall.setupDuration =
-                VOICE_CALL_SESSION__SETUP_DURATION__CALL_SETUP_DURATION_EXTREMELY_FAST;
         expectedCall.setupDurationMillis = 80;
         expectedCall.setupFailed = false;
         expectedCall.codecBitmask = 1L << AudioCodec.AUDIO_CODEC_AMR;
@@ -908,6 +895,7 @@
 
     @Test
     @SmallTest
+    @Ignore("b/256234604")
     public void singleImsCall_ratSwitchToUnknown() {
         setServiceState(mServiceState, TelephonyManager.NETWORK_TYPE_LTE);
         doReturn(true).when(mImsConnection0).isIncoming();
@@ -921,7 +909,6 @@
                         VOICE_CALL_SESSION__DIRECTION__CALL_DIRECTION_MT,
                         TelephonyManager.NETWORK_TYPE_LTE,
                         ImsReasonInfo.CODE_USER_TERMINATED);
-        expectedCall.setupDuration = 1;
         expectedCall.setupDurationMillis = 80;
         expectedCall.setupFailed = false;
         expectedCall.codecBitmask = 1L << AudioCodec.AUDIO_CODEC_AMR;
@@ -1052,8 +1039,6 @@
                         VOICE_CALL_SESSION__DIRECTION__CALL_DIRECTION_MT,
                         TelephonyManager.NETWORK_TYPE_LTE,
                         ImsReasonInfo.CODE_USER_TERMINATED);
-        expectedCall.setupDuration =
-                VOICE_CALL_SESSION__SETUP_DURATION__CALL_SETUP_DURATION_EXTREMELY_FAST;
         expectedCall.setupDurationMillis = 80;
         expectedCall.setupFailed = false;
         expectedCall.codecBitmask = 1L << AudioCodec.AUDIO_CODEC_AMR;
@@ -1105,8 +1090,6 @@
                         VOICE_CALL_SESSION__DIRECTION__CALL_DIRECTION_MO,
                         TelephonyManager.NETWORK_TYPE_LTE,
                         ImsReasonInfo.CODE_USER_TERMINATED_BY_REMOTE);
-        expectedCall0.setupDuration =
-                VOICE_CALL_SESSION__SETUP_DURATION__CALL_SETUP_DURATION_EXTREMELY_FAST;
         expectedCall0.setupDurationMillis = 80;
         expectedCall0.setupFailed = false;
         expectedCall0.codecBitmask = 1L << AudioCodec.AUDIO_CODEC_AMR;
@@ -1129,8 +1112,6 @@
                         VOICE_CALL_SESSION__DIRECTION__CALL_DIRECTION_MT,
                         TelephonyManager.NETWORK_TYPE_LTE,
                         ImsReasonInfo.CODE_USER_TERMINATED);
-        expectedCall1.setupDuration =
-                VOICE_CALL_SESSION__SETUP_DURATION__CALL_SETUP_DURATION_EXTREMELY_FAST;
         expectedCall1.setupDurationMillis = 20;
         expectedCall1.setupFailed = false;
         expectedCall1.codecBitmask = 1L << AudioCodec.AUDIO_CODEC_AMR;
@@ -1235,8 +1216,6 @@
                         VOICE_CALL_SESSION__DIRECTION__CALL_DIRECTION_MO,
                         TelephonyManager.NETWORK_TYPE_LTE,
                         ImsReasonInfo.CODE_USER_TERMINATED);
-        expectedCall0.setupDuration =
-                VOICE_CALL_SESSION__SETUP_DURATION__CALL_SETUP_DURATION_EXTREMELY_FAST;
         expectedCall0.setupDurationMillis = 80;
         expectedCall0.setupFailed = false;
         expectedCall0.codecBitmask = 1L << AudioCodec.AUDIO_CODEC_AMR;
@@ -1259,8 +1238,6 @@
                         VOICE_CALL_SESSION__DIRECTION__CALL_DIRECTION_MT,
                         TelephonyManager.NETWORK_TYPE_LTE,
                         ImsReasonInfo.CODE_USER_TERMINATED_BY_REMOTE);
-        expectedCall1.setupDuration =
-                VOICE_CALL_SESSION__SETUP_DURATION__CALL_SETUP_DURATION_EXTREMELY_FAST;
         expectedCall1.setupDurationMillis = 20;
         expectedCall1.setupFailed = false;
         expectedCall1.codecBitmask = 1L << AudioCodec.AUDIO_CODEC_AMR;
@@ -1365,8 +1342,6 @@
                         VOICE_CALL_SESSION__DIRECTION__CALL_DIRECTION_MO,
                         TelephonyManager.NETWORK_TYPE_LTE,
                         ImsReasonInfo.CODE_USER_TERMINATED);
-        expectedCall0.setupDuration =
-                VOICE_CALL_SESSION__SETUP_DURATION__CALL_SETUP_DURATION_EXTREMELY_FAST;
         expectedCall0.setupDurationMillis = 80;
         expectedCall0.setupFailed = false;
         expectedCall0.codecBitmask = 1L << AudioCodec.AUDIO_CODEC_AMR;
@@ -1387,8 +1362,6 @@
                         VOICE_CALL_SESSION__DIRECTION__CALL_DIRECTION_MT,
                         TelephonyManager.NETWORK_TYPE_LTE,
                         ImsReasonInfo.CODE_USER_TERMINATED_BY_REMOTE);
-        expectedCall1.setupDuration =
-                VOICE_CALL_SESSION__SETUP_DURATION__CALL_SETUP_DURATION_EXTREMELY_FAST;
         expectedCall1.setupDurationMillis = 20;
         expectedCall1.setupFailed = false;
         expectedCall1.codecBitmask = 1L << AudioCodec.AUDIO_CODEC_AMR;
@@ -1479,8 +1452,6 @@
                         DisconnectCause.NORMAL);
         expectedCall.ratAtEnd = TelephonyManager.NETWORK_TYPE_UMTS;
         expectedCall.bandAtEnd = 0;
-        expectedCall.setupDuration =
-                VOICE_CALL_SESSION__SETUP_DURATION__CALL_SETUP_DURATION_VERY_SLOW;
         expectedCall.setupDurationMillis = 5000;
         expectedCall.disconnectExtraCode = PreciseDisconnectCause.CALL_REJECTED;
         expectedCall.ratSwitchCount = 1L;
@@ -1599,8 +1570,6 @@
         expectedCall.ratAtConnected = TelephonyManager.NETWORK_TYPE_UMTS;
         expectedCall.ratAtEnd = TelephonyManager.NETWORK_TYPE_UMTS;
         expectedCall.bandAtEnd = 0;
-        expectedCall.setupDuration =
-                VOICE_CALL_SESSION__SETUP_DURATION__CALL_SETUP_DURATION_VERY_SLOW;
         expectedCall.setupDurationMillis = 5000;
         expectedCall.disconnectExtraCode = PreciseDisconnectCause.NORMAL;
         expectedCall.ratSwitchCount = 1L;
@@ -1665,8 +1634,6 @@
                         VOICE_CALL_SESSION__DIRECTION__CALL_DIRECTION_MT,
                         TelephonyManager.NETWORK_TYPE_UMTS,
                         DisconnectCause.NORMAL);
-        expectedCall.setupDuration =
-                VOICE_CALL_SESSION__SETUP_DURATION__CALL_SETUP_DURATION_UNKNOWN;
         expectedCall.setupDurationMillis = 0;
         expectedCall.disconnectExtraCode = PreciseDisconnectCause.CALL_REJECTED;
         expectedCall.setupFailed = true;
@@ -1722,8 +1689,6 @@
                         VOICE_CALL_SESSION__DIRECTION__CALL_DIRECTION_MT,
                         TelephonyManager.NETWORK_TYPE_UMTS,
                         DisconnectCause.NORMAL);
-        expectedCall.setupDuration =
-                VOICE_CALL_SESSION__SETUP_DURATION__CALL_SETUP_DURATION_ULTRA_FAST;
         expectedCall.setupDurationMillis = 500;
         expectedCall.disconnectExtraCode = PreciseDisconnectCause.NORMAL;
         expectedCall.setupFailed = false;
@@ -1782,8 +1747,6 @@
                         VOICE_CALL_SESSION__DIRECTION__CALL_DIRECTION_MT,
                         TelephonyManager.NETWORK_TYPE_LTE,
                         ImsReasonInfo.CODE_LOCAL_HO_NOT_FEASIBLE);
-        expectedCall.setupDuration =
-                VOICE_CALL_SESSION__SETUP_DURATION__CALL_SETUP_DURATION_EXTREMELY_FAST;
         expectedCall.setupDurationMillis = 80;
         expectedCall.setupFailed = false;
         expectedCall.srvccFailureCount = 2L;
@@ -1861,8 +1824,6 @@
                         VOICE_CALL_SESSION__DIRECTION__CALL_DIRECTION_MT,
                         TelephonyManager.NETWORK_TYPE_LTE,
                         ImsReasonInfo.CODE_USER_TERMINATED);
-        expectedCall.setupDuration =
-                VOICE_CALL_SESSION__SETUP_DURATION__CALL_SETUP_DURATION_EXTREMELY_FAST;
         expectedCall.setupDurationMillis = 80;
         expectedCall.setupFailed = false;
         expectedCall.srvccCancellationCount = 2L;
@@ -1932,8 +1893,6 @@
                         TelephonyManager.NETWORK_TYPE_LTE,
                         DisconnectCause.NORMAL);
         expectedCall.disconnectExtraCode = PreciseDisconnectCause.NORMAL;
-        expectedCall.setupDuration =
-                VOICE_CALL_SESSION__SETUP_DURATION__CALL_SETUP_DURATION_EXTREMELY_FAST;
         expectedCall.setupDurationMillis = 80;
         expectedCall.setupFailed = false;
         expectedCall.srvccCancellationCount = 1L;
@@ -2029,8 +1988,6 @@
                         TelephonyManager.NETWORK_TYPE_LTE,
                         DisconnectCause.NORMAL);
         expectedCall0.disconnectExtraCode = PreciseDisconnectCause.NORMAL;
-        expectedCall0.setupDuration =
-                VOICE_CALL_SESSION__SETUP_DURATION__CALL_SETUP_DURATION_EXTREMELY_FAST;
         expectedCall0.setupDurationMillis = 80;
         expectedCall0.setupFailed = false;
         expectedCall0.codecBitmask = 1L << AudioCodec.AUDIO_CODEC_AMR;
@@ -2058,8 +2015,6 @@
                         TelephonyManager.NETWORK_TYPE_LTE,
                         DisconnectCause.NORMAL);
         expectedCall1.disconnectExtraCode = PreciseDisconnectCause.NORMAL;
-        expectedCall1.setupDuration =
-                VOICE_CALL_SESSION__SETUP_DURATION__CALL_SETUP_DURATION_EXTREMELY_FAST;
         expectedCall1.setupDurationMillis = 20;
         expectedCall1.setupFailed = false;
         expectedCall1.codecBitmask = 1L << AudioCodec.AUDIO_CODEC_AMR;
@@ -2303,7 +2258,6 @@
         call.bearerAtStart = bearer;
         call.bearerAtEnd = bearer;
         call.direction = direction;
-        call.setupDuration = VOICE_CALL_SESSION__SETUP_DURATION__CALL_SETUP_DURATION_UNKNOWN;
         call.setupDurationMillis = 0;
         call.setupFailed = true;
         call.disconnectReasonCode = reason;
@@ -2338,7 +2292,6 @@
         call.bearerAtStart = bearer;
         call.bearerAtEnd = bearer;
         call.direction = direction;
-        call.setupDuration = VOICE_CALL_SESSION__SETUP_DURATION__CALL_SETUP_DURATION_UNKNOWN;
         call.setupDurationMillis = 0;
         call.setupFailed = true;
         call.disconnectReasonCode = reason;
diff --git a/tests/telephonytests/src/com/android/internal/telephony/nitz/OWNERS b/tests/telephonytests/src/com/android/internal/telephony/nitz/OWNERS
new file mode 100644
index 0000000..be0513d
--- /dev/null
+++ b/tests/telephonytests/src/com/android/internal/telephony/nitz/OWNERS
@@ -0,0 +1,2 @@
+# Bug component: 847766
+include platform/frameworks/base:/services/core/java/com/android/server/timezonedetector/OWNERS
diff --git a/tests/telephonytests/src/com/android/internal/telephony/uicc/UiccCarrierPrivilegeRulesTest.java b/tests/telephonytests/src/com/android/internal/telephony/uicc/UiccCarrierPrivilegeRulesTest.java
index c885f5a..3deb501 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/uicc/UiccCarrierPrivilegeRulesTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/uicc/UiccCarrierPrivilegeRulesTest.java
@@ -42,7 +42,6 @@
 import org.mockito.invocation.InvocationOnMock;
 import org.mockito.stubbing.Answer;
 
-import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 import java.util.concurrent.atomic.AtomicReference;
@@ -581,28 +580,20 @@
 
         // Read binary - since params are identical across files, we need to keep track of which
         // file was selected most recently and give back that content.
-        Map<String, String> binaryContent =
-                new HashMap<>() {
-                    {
-                        // ODF
-                        put("5031", "A706300404025207");
-                        // DODF
-                        put(
-                                "5207",
-                                "A1293000300F0C0D4750205345204163632043746CA1143012060A2A864886FC6B"
-                                        + "81480101300404024200");
-                        // ACMF
-                        put("4200", "301004080102030405060708300404024300");
-                        // ACRF
-                        put("4300", "3010A0080406FFFFFFFFFFFF300404024310");
-                        // ACCF
-                        put(
-                                "4310",
-                                "30220420B9CFCE1C47A6AC713442718F15EF55B00B3A6D1A6D48CB46249FA8EB51"
-                                        + "465350302204204C36AF4A5BDAD97C1F3D8B283416D244496C2AC5EA"
-                                        + "FE8226079EF6F676FD1859");
-                    }
-                };
+        Map<String, String> binaryContent = Map.of(
+                // ODF
+                "5031", "A706300404025207",
+                // DODF
+                "5207", "A1293000300F0C0D4750205345204163632043746CA1143012060A2A864886FC6B"
+                        + "81480101300404024200",
+                // ACMF
+                "4200", "301004080102030405060708300404024300",
+                // ACRF
+                "4300", "3010A0080406FFFFFFFFFFFF300404024310",
+                // ACCF
+                "4310", "30220420B9CFCE1C47A6AC713442718F15EF55B00B3A6D1A6D48CB46249FA8EB51"
+                        + "465350302204204C36AF4A5BDAD97C1F3D8B283416D244496C2AC5EA"
+                        + "FE8226079EF6F676FD1859");
         doAnswer(new Answer<Void>() {
             @Override
             public Void answer(InvocationOnMock invocation) throws Throwable {
@@ -687,21 +678,15 @@
 
         // Read binary - since params are identical across files, we need to keep track of which
         // file was selected most recently and give back that content.
-        Map<String, String> binaryContent =
-                new HashMap<>() {
-                    {
-                        // ODF fails
-                        put("5031", "");
-                        // ACRF
-                        put("4300", "3010A0080406FFFFFFFFFFFF300404024310");
-                        // ACCF
-                        put(
-                                "4310",
-                                "30220420B9CFCE1C47A6AC713442718F15EF55B00B3A6D1A6D48CB46249FA8EB51"
-                                        + "465350302204204C36AF4A5BDAD97C1F3D8B283416D244496C2AC5EA"
-                                        + "FE8226079EF6F676FD1859");
-                    }
-                };
+        Map<String, String> binaryContent = Map.of(
+                // ODF fails
+                "5031", "",
+                // ACRF
+                "4300", "3010A0080406FFFFFFFFFFFF300404024310",
+                // ACCF
+                "4310", "30220420B9CFCE1C47A6AC713442718F15EF55B00B3A6D1A6D48CB46249FA8EB51"
+                        + "465350302204204C36AF4A5BDAD97C1F3D8B283416D244496C2AC5EA"
+                        + "FE8226079EF6F676FD1859");
         doAnswer(new Answer<Void>() {
             @Override
             public Void answer(InvocationOnMock invocation) throws Throwable {