Merge changes from topics "forced-non-staged-apex-update", "non-staged-flag" into main

* changes:
  Add an install flag to force non-staged APEX update
  Add --non-staged flag
diff --git a/core/api/module-lib-current.txt b/core/api/module-lib-current.txt
index 13a4899..6a4c67b 100644
--- a/core/api/module-lib-current.txt
+++ b/core/api/module-lib-current.txt
@@ -90,6 +90,7 @@
   public abstract class Context {
     method @NonNull public android.os.UserHandle getUser();
     field public static final String PAC_PROXY_SERVICE = "pac_proxy";
+    field public static final String REMOTE_AUTH_SERVICE = "remote_auth";
     field public static final String TEST_NETWORK_SERVICE = "test_network";
   }
 
diff --git a/core/java/android/content/Context.java b/core/java/android/content/Context.java
index 7de7c67..21d4b64 100644
--- a/core/java/android/content/Context.java
+++ b/core/java/android/content/Context.java
@@ -6059,6 +6059,18 @@
 
     /**
      * Use with {@link #getSystemService(String)} to retrieve a
+     * {@link android.remoteauth.RemoteAuthManager} to discover,
+     * register and authenticate via remote authenticator  devices.
+     *
+     * @see #getSystemService(String)
+     * @see android.remoteauth.RemoteAuthManager
+     * @hide
+     */
+    @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
+    public static final String REMOTE_AUTH_SERVICE = "remote_auth";
+
+    /**
+     * Use with {@link #getSystemService(String)} to retrieve a
      * {@link android.app.ambientcontext.AmbientContextManager}.
      *
      * @see #getSystemService(String)
diff --git a/core/java/android/content/res/Resources.java b/core/java/android/content/res/Resources.java
index 9b16949..c8dbfc9 100644
--- a/core/java/android/content/res/Resources.java
+++ b/core/java/android/content/res/Resources.java
@@ -53,6 +53,7 @@
 import android.graphics.drawable.DrawableInflater;
 import android.os.Build;
 import android.os.Bundle;
+import android.os.SystemClock;
 import android.util.ArrayMap;
 import android.util.ArraySet;
 import android.util.AttributeSet;
@@ -132,6 +133,11 @@
     private static final Object sSync = new Object();
     private final Object mUpdateLock = new Object();
 
+    /**
+     * Controls whether we should preload resources during zygote init.
+     */
+    private static final boolean PRELOAD_RESOURCES = true;
+
     // Used by BridgeResources in layoutlib
     @UnsupportedAppUsage
     static Resources mSystem = null;
@@ -2666,6 +2672,98 @@
         }
     }
 
+    /**
+     * Load in commonly used resources, so they can be shared across processes.
+     *
+     * These tend to be a few Kbytes, but are frequently in the 20-40K range, and occasionally even
+     * larger.
+     * @hide
+     */
+    @UnsupportedAppUsage
+    public static void preloadResources() {
+        try {
+            final Resources sysRes = Resources.getSystem();
+            sysRes.startPreloading();
+            if (PRELOAD_RESOURCES) {
+                Log.i(TAG, "Preloading resources...");
+
+                long startTime = SystemClock.uptimeMillis();
+                TypedArray ar = sysRes.obtainTypedArray(
+                        com.android.internal.R.array.preloaded_drawables);
+                int numberOfEntries = preloadDrawables(sysRes, ar);
+                ar.recycle();
+                Log.i(TAG, "...preloaded " + numberOfEntries + " resources in "
+                        + (SystemClock.uptimeMillis() - startTime) + "ms.");
+
+                startTime = SystemClock.uptimeMillis();
+                ar = sysRes.obtainTypedArray(
+                        com.android.internal.R.array.preloaded_color_state_lists);
+                numberOfEntries = preloadColorStateLists(sysRes, ar);
+                ar.recycle();
+                Log.i(TAG, "...preloaded " + numberOfEntries + " resources in "
+                        + (SystemClock.uptimeMillis() - startTime) + "ms.");
+
+                if (sysRes.getBoolean(
+                        com.android.internal.R.bool.config_freeformWindowManagement)) {
+                    startTime = SystemClock.uptimeMillis();
+                    ar = sysRes.obtainTypedArray(
+                            com.android.internal.R.array.preloaded_freeform_multi_window_drawables);
+                    numberOfEntries = preloadDrawables(sysRes, ar);
+                    ar.recycle();
+                    Log.i(TAG, "...preloaded " + numberOfEntries + " resource in "
+                            + (SystemClock.uptimeMillis() - startTime) + "ms.");
+                }
+            }
+            sysRes.finishPreloading();
+        } catch (RuntimeException e) {
+            Log.w(TAG, "Failure preloading resources", e);
+        }
+    }
+
+    private static int preloadColorStateLists(Resources resources, TypedArray ar) {
+        final int numberOfEntries = ar.length();
+        for (int i = 0; i < numberOfEntries; i++) {
+            int id = ar.getResourceId(i, 0);
+
+            if (id != 0) {
+                if (resources.getColorStateList(id, null) == null) {
+                    throw new IllegalArgumentException(
+                            "Unable to find preloaded color resource #0x"
+                                    + Integer.toHexString(id)
+                                    + " (" + ar.getString(i) + ")");
+                }
+            }
+        }
+        return numberOfEntries;
+    }
+
+    private static int preloadDrawables(Resources resources, TypedArray ar) {
+        final int numberOfEntries = ar.length();
+        for (int i = 0; i < numberOfEntries; i++) {
+            int id = ar.getResourceId(i, 0);
+
+            if (id != 0) {
+                if (resources.getDrawable(id, null) == null) {
+                    throw new IllegalArgumentException(
+                            "Unable to find preloaded drawable resource #0x"
+                                    + Integer.toHexString(id)
+                                    + " (" + ar.getString(i) + ")");
+                }
+            }
+        }
+        return numberOfEntries;
+    }
+
+    /**
+     * Clear the cache when the framework resources packages is changed.
+     * @hide
+     */
+    @VisibleForTesting
+    public static void resetPreloadDrawableStateCache() {
+        ResourcesImpl.resetDrawableStateCache();
+        preloadResources();
+    }
+
     /** @hide */
     public void dump(PrintWriter pw, String prefix) {
         pw.println(prefix + "class=" + getClass());
diff --git a/core/java/android/content/res/ResourcesImpl.java b/core/java/android/content/res/ResourcesImpl.java
index 3bb237a..480e43e 100644
--- a/core/java/android/content/res/ResourcesImpl.java
+++ b/core/java/android/content/res/ResourcesImpl.java
@@ -52,6 +52,7 @@
 import android.util.Xml;
 import android.view.DisplayAdjustments;
 
+import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.util.GrowingArrayUtils;
 
 import libcore.util.NativeAllocationRegistry;
@@ -159,6 +160,23 @@
     }
 
     /**
+     * Clear the cache when the framework resources packages is changed.
+     *
+     * It's only used in the test initial function instead of regular app behaviors. It doesn't
+     * guarantee the thread-safety so mark this with @VisibleForTesting.
+     */
+    @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE)
+    static void resetDrawableStateCache() {
+        synchronized (sSync) {
+            sPreloadedDrawables[0].clear();
+            sPreloadedDrawables[1].clear();
+            sPreloadedColorDrawables.clear();
+            sPreloadedComplexColors.clear();
+            sPreloaded = false;
+        }
+    }
+
+    /**
      * Creates a new ResourcesImpl object with CompatibilityInfo.
      *
      * @param assets Previously created AssetManager.
diff --git a/core/java/com/android/internal/os/ZygoteInit.java b/core/java/com/android/internal/os/ZygoteInit.java
index 85cb15b..b3938b4 100644
--- a/core/java/com/android/internal/os/ZygoteInit.java
+++ b/core/java/com/android/internal/os/ZygoteInit.java
@@ -26,7 +26,6 @@
 import android.compat.annotation.UnsupportedAppUsage;
 import android.content.pm.SharedLibraryInfo;
 import android.content.res.Resources;
-import android.content.res.TypedArray;
 import android.os.Build;
 import android.os.Environment;
 import android.os.IInstalld;
@@ -102,21 +101,10 @@
     private static final String SOCKET_NAME_ARG = "--socket-name=";
 
     /**
-     * Used to pre-load resources.
-     */
-    @UnsupportedAppUsage
-    private static Resources mResources;
-
-    /**
      * The path of a file that contains classes to preload.
      */
     private static final String PRELOADED_CLASSES = "/system/etc/preloaded-classes";
 
-    /**
-     * Controls whether we should preload resources during zygote init.
-     */
-    private static final boolean PRELOAD_RESOURCES = true;
-
     private static final int UNPRIVILEGED_UID = 9999;
     private static final int UNPRIVILEGED_GID = 9999;
 
@@ -143,7 +131,7 @@
         cacheNonBootClasspathClassLoaders();
         bootTimingsTraceLog.traceEnd(); // CacheNonBootClasspathClassLoaders
         bootTimingsTraceLog.traceBegin("PreloadResources");
-        preloadResources();
+        Resources.preloadResources();
         bootTimingsTraceLog.traceEnd(); // PreloadResources
         Trace.traceBegin(Trace.TRACE_TAG_DALVIK, "PreloadAppProcessHALs");
         nativePreloadAppProcessHALs();
@@ -414,87 +402,6 @@
     }
 
     /**
-     * Load in commonly used resources, so they can be shared across processes.
-     *
-     * These tend to be a few Kbytes, but are frequently in the 20-40K range, and occasionally even
-     * larger.
-     */
-    private static void preloadResources() {
-        try {
-            mResources = Resources.getSystem();
-            mResources.startPreloading();
-            if (PRELOAD_RESOURCES) {
-                Log.i(TAG, "Preloading resources...");
-
-                long startTime = SystemClock.uptimeMillis();
-                TypedArray ar = mResources.obtainTypedArray(
-                        com.android.internal.R.array.preloaded_drawables);
-                int N = preloadDrawables(ar);
-                ar.recycle();
-                Log.i(TAG, "...preloaded " + N + " resources in "
-                        + (SystemClock.uptimeMillis() - startTime) + "ms.");
-
-                startTime = SystemClock.uptimeMillis();
-                ar = mResources.obtainTypedArray(
-                        com.android.internal.R.array.preloaded_color_state_lists);
-                N = preloadColorStateLists(ar);
-                ar.recycle();
-                Log.i(TAG, "...preloaded " + N + " resources in "
-                        + (SystemClock.uptimeMillis() - startTime) + "ms.");
-
-                if (mResources.getBoolean(
-                        com.android.internal.R.bool.config_freeformWindowManagement)) {
-                    startTime = SystemClock.uptimeMillis();
-                    ar = mResources.obtainTypedArray(
-                            com.android.internal.R.array.preloaded_freeform_multi_window_drawables);
-                    N = preloadDrawables(ar);
-                    ar.recycle();
-                    Log.i(TAG, "...preloaded " + N + " resource in "
-                            + (SystemClock.uptimeMillis() - startTime) + "ms.");
-                }
-            }
-            mResources.finishPreloading();
-        } catch (RuntimeException e) {
-            Log.w(TAG, "Failure preloading resources", e);
-        }
-    }
-
-    private static int preloadColorStateLists(TypedArray ar) {
-        int N = ar.length();
-        for (int i = 0; i < N; i++) {
-            int id = ar.getResourceId(i, 0);
-
-            if (id != 0) {
-                if (mResources.getColorStateList(id, null) == null) {
-                    throw new IllegalArgumentException(
-                            "Unable to find preloaded color resource #0x"
-                                    + Integer.toHexString(id)
-                                    + " (" + ar.getString(i) + ")");
-                }
-            }
-        }
-        return N;
-    }
-
-
-    private static int preloadDrawables(TypedArray ar) {
-        int N = ar.length();
-        for (int i = 0; i < N; i++) {
-            int id = ar.getResourceId(i, 0);
-
-            if (id != 0) {
-                if (mResources.getDrawable(id, null) == null) {
-                    throw new IllegalArgumentException(
-                            "Unable to find preloaded drawable resource #0x"
-                                    + Integer.toHexString(id)
-                                    + " (" + ar.getString(i) + ")");
-                }
-            }
-        }
-        return N;
-    }
-
-    /**
      * Runs several special GCs to try to clean up a few generations of softly- and final-reachable
      * objects, along with any other garbage. This is only useful just before a fork().
      */
diff --git a/core/jni/android_util_Binder.cpp b/core/jni/android_util_Binder.cpp
index c198797..9dce5e3 100644
--- a/core/jni/android_util_Binder.cpp
+++ b/core/jni/android_util_Binder.cpp
@@ -40,7 +40,6 @@
 #include <binder/Stability.h>
 #include <binderthreadstate/CallerUtils.h>
 #include <cutils/atomic.h>
-#include <cutils/threads.h>
 #include <log/log.h>
 #include <utils/KeyedVector.h>
 #include <utils/List.h>
diff --git a/services/accessibility/java/com/android/server/accessibility/gestures/TouchExplorer.java b/services/accessibility/java/com/android/server/accessibility/gestures/TouchExplorer.java
index 2cf0e3e..33544bc 100644
--- a/services/accessibility/java/com/android/server/accessibility/gestures/TouchExplorer.java
+++ b/services/accessibility/java/com/android/server/accessibility/gestures/TouchExplorer.java
@@ -1341,6 +1341,8 @@
                 Slog.e(LOG_TAG, "Unable to find a valid pointer for touch exploration.");
                 return;
             }
+            // Send hover exit if we haven't closed a previous touch exploration event stream.
+            sendHoverExitAndTouchExplorationGestureEndIfNeeded(pointerId);
             final int pointerIdBits = (1 << pointerId);
             final int policyFlags = mState.getLastReceivedPolicyFlags();
             mSendHoverEnterAndMoveDelayed.setPointerIdBits(pointerIdBits);
diff --git a/services/core/java/com/android/server/vcn/TelephonySubscriptionTracker.java b/services/core/java/com/android/server/vcn/TelephonySubscriptionTracker.java
index ca4a32f..099c9ae 100644
--- a/services/core/java/com/android/server/vcn/TelephonySubscriptionTracker.java
+++ b/services/core/java/com/android/server/vcn/TelephonySubscriptionTracker.java
@@ -16,9 +16,6 @@
 
 package com.android.server.vcn;
 
-import static android.telephony.CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED;
-import static android.telephony.CarrierConfigManager.EXTRA_SLOT_INDEX;
-import static android.telephony.CarrierConfigManager.EXTRA_SUBSCRIPTION_INDEX;
 import static android.telephony.SubscriptionManager.INVALID_SIM_SLOT_INDEX;
 import static android.telephony.SubscriptionManager.INVALID_SUBSCRIPTION_ID;
 import static android.telephony.TelephonyManager.ACTION_MULTI_SIM_CONFIG_CHANGED;
@@ -48,7 +45,6 @@
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.annotations.VisibleForTesting.Visibility;
 import com.android.internal.util.IndentingPrintWriter;
-import com.android.server.vcn.util.PersistableBundleUtils;
 import com.android.server.vcn.util.PersistableBundleUtils.PersistableBundleWrapper;
 
 import java.util.ArrayList;
@@ -109,6 +105,12 @@
 
     @NonNull private TelephonySubscriptionSnapshot mCurrentSnapshot;
 
+    @NonNull
+    private final CarrierConfigManager.CarrierConfigChangeListener mCarrierConfigChangeListener =
+            (int logicalSlotIndex, int subscriptionId, int carrierId, int specificCarrierId) ->
+                    handleActionCarrierConfigChanged(logicalSlotIndex, subscriptionId);
+
+
     public TelephonySubscriptionTracker(
             @NonNull Context context,
             @NonNull Handler handler,
@@ -149,13 +151,14 @@
     public void register() {
         final HandlerExecutor executor = new HandlerExecutor(mHandler);
         final IntentFilter filter = new IntentFilter();
-        filter.addAction(ACTION_CARRIER_CONFIG_CHANGED);
         filter.addAction(ACTION_MULTI_SIM_CONFIG_CHANGED);
 
         mContext.registerReceiver(this, filter, null, mHandler);
         mSubscriptionManager.addOnSubscriptionsChangedListener(
                 executor, mSubscriptionChangedListener);
         mTelephonyManager.registerTelephonyCallback(executor, mActiveDataSubIdListener);
+        mCarrierConfigManager.registerCarrierConfigChangeListener(executor,
+                mCarrierConfigChangeListener);
 
         registerCarrierPrivilegesCallbacks();
     }
@@ -197,6 +200,7 @@
         mContext.unregisterReceiver(this);
         mSubscriptionManager.removeOnSubscriptionsChangedListener(mSubscriptionChangedListener);
         mTelephonyManager.unregisterTelephonyCallback(mActiveDataSubIdListener);
+        mCarrierConfigManager.unregisterCarrierConfigChangeListener(mCarrierConfigChangeListener);
 
         unregisterCarrierPrivilegesCallbacks();
     }
@@ -273,7 +277,7 @@
     }
 
     /**
-     * Broadcast receiver for ACTION_CARRIER_CONFIG_CHANGED
+     * Broadcast receiver for ACTION_MULTI_SIM_CONFIG_CHANGED
      *
      * <p>The broadcast receiver is registered with mHandler, so callbacks & broadcasts are all
      * serialized on mHandler, avoiding the need for locking.
@@ -281,9 +285,6 @@
     @Override
     public void onReceive(Context context, Intent intent) {
         switch (intent.getAction()) {
-            case ACTION_CARRIER_CONFIG_CHANGED:
-                handleActionCarrierConfigChanged(context, intent);
-                break;
             case ACTION_MULTI_SIM_CONFIG_CHANGED:
                 handleActionMultiSimConfigChanged(context, intent);
                 break;
@@ -310,26 +311,21 @@
         handleSubscriptionsChanged();
     }
 
-    private void handleActionCarrierConfigChanged(Context context, Intent intent) {
-        // Accept sticky broadcasts; if CARRIER_CONFIG_CHANGED was previously broadcast and it
-        // already was for an identified carrier, we can stop waiting for initial load to complete
-        final int subId = intent.getIntExtra(EXTRA_SUBSCRIPTION_INDEX, INVALID_SUBSCRIPTION_ID);
-        final int slotId = intent.getIntExtra(EXTRA_SLOT_INDEX, INVALID_SIM_SLOT_INDEX);
-
+    private void handleActionCarrierConfigChanged(int slotId, int subId) {
         if (slotId == INVALID_SIM_SLOT_INDEX) {
             return;
         }
 
         if (SubscriptionManager.isValidSubscriptionId(subId)) {
-            final PersistableBundle carrierConfig = mCarrierConfigManager.getConfigForSubId(subId);
+            // Get only configs as needed to save memory.
+            final PersistableBundle carrierConfig = mCarrierConfigManager.getConfigForSubId(subId,
+                    VcnManager.VCN_RELATED_CARRIER_CONFIG_KEYS);
             if (mDeps.isConfigForIdentifiedCarrier(carrierConfig)) {
                 mReadySubIdsBySlotId.put(slotId, subId);
 
-                final PersistableBundle minimized =
-                        PersistableBundleUtils.minimizeBundle(
-                                carrierConfig, VcnManager.VCN_RELATED_CARRIER_CONFIG_KEYS);
-                if (minimized != null) {
-                    mSubIdToCarrierConfigMap.put(subId, new PersistableBundleWrapper(minimized));
+                if (!carrierConfig.isEmpty()) {
+                    mSubIdToCarrierConfigMap.put(subId,
+                            new PersistableBundleWrapper(carrierConfig));
                 }
                 handleSubscriptionsChanged();
             }
diff --git a/telephony/java/android/telephony/SubscriptionManager.java b/telephony/java/android/telephony/SubscriptionManager.java
index 81eb836..96dc44a 100644
--- a/telephony/java/android/telephony/SubscriptionManager.java
+++ b/telephony/java/android/telephony/SubscriptionManager.java
@@ -2218,46 +2218,46 @@
     }
 
     /**
-     * Get an array of subscription ids for specified logical SIM slot Index.
+     * Get an array of subscription ids for the specified logical SIM slot Index. The maximum size
+     * of the array is 1. This API was mistakenly designed to return multiple subscription ids,
+     * which is not possible in the current Android telephony architecture.
      *
      * @param slotIndex The logical SIM slot index.
      *
-     * @return subscription Ids or {@code null} if the given slot index is not valid or there are
-     * no active subscription in the slot. In the implementation today, there will be no more
-     * than one subscriptions per logical SIM slot.
+     * @return Subscription id of the active subscription on the specified logical SIM slot index.
+     * If SIM is absent on the slot, a single element array of {@link #INVALID_SUBSCRIPTION_ID} will
+     * be returned. {@code null} if the provided {@code slotIndex} is not valid.
      *
      * @deprecated Use {@link #getSubscriptionId(int)} instead.
      */
     @Deprecated
     @Nullable
     public int[] getSubscriptionIds(int slotIndex) {
-        int subId = getSubscriptionId(slotIndex);
-        if (!isValidSubscriptionId(subId)) {
+        if (!isValidSlotIndex(slotIndex)) {
             return null;
         }
         return new int[]{getSubscriptionId(slotIndex)};
     }
 
-    /** @hide */
-    @UnsupportedAppUsage
+    /**
+     * Get an array of subscription ids for the specified logical SIM slot Index. The maximum size
+     * of the array is 1. This API was mistakenly designed to return multiple subscription ids,
+     * which is not possible in the current Android telephony architecture.
+     *
+     * @param slotIndex The logical SIM slot index.
+     *
+     * @return Subscription id of the active subscription on the specified logical SIM slot index.
+     * If SIM is absent on the slot, a single element array of {@link #INVALID_SUBSCRIPTION_ID} will
+     * be returned. {@code null} if the provided {@code slotIndex} is not valid.
+     *
+     * @deprecated Use {@link #getSubscriptionId(int)} instead.
+     * @hide
+     */
     public static int[] getSubId(int slotIndex) {
         if (!isValidSlotIndex(slotIndex)) {
-            logd("[getSubId]- fail");
             return null;
         }
-
-        int[] subId = null;
-
-        try {
-            ISub iSub = TelephonyManager.getSubscriptionService();
-            if (iSub != null) {
-                subId = iSub.getSubIds(slotIndex);
-            }
-        } catch (RemoteException ex) {
-            // ignore it
-        }
-
-        return subId;
+        return new int[]{getSubscriptionId(slotIndex)};
     }
 
     /**
@@ -3628,17 +3628,10 @@
     }
 
     /**
-     * Enables or disables a subscription. This is currently used in the settings page. It will
-     * fail and return false if operation is not supported or failed.
+     * Enable or disable a subscription. This method is same as
+     * {@link #setUiccApplicationsEnabled(int, boolean)}.
      *
-     * To disable an active subscription on a physical (non-Euicc) SIM,
-     * {@link #canDisablePhysicalSubscription} needs to be true.
-     *
-     * <p>
-     * Permissions android.Manifest.permission.MODIFY_PHONE_STATE is required
-     *
-     * @param subscriptionId Subscription to be enabled or disabled. It could be a eSIM or pSIM
-     * subscription.
+     * @param subscriptionId Subscription to be enabled or disabled.
      * @param enable whether user is turning it on or off.
      *
      * @return whether the operation is successful.
@@ -3648,19 +3641,15 @@
     @SystemApi
     @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE)
     public boolean setSubscriptionEnabled(int subscriptionId, boolean enable) {
-        if (VDBG) {
-            logd("setSubscriptionActivated subId= " + subscriptionId + " enable " + enable);
-        }
         try {
             ISub iSub = TelephonyManager.getSubscriptionService();
             if (iSub != null) {
-                return iSub.setSubscriptionEnabled(enable, subscriptionId);
+                iSub.setUiccApplicationsEnabled(enable, subscriptionId);
             }
         } catch (RemoteException ex) {
-            // ignore it
+            return false;
         }
-
-        return false;
+        return true;
     }
 
     /**
@@ -3683,11 +3672,7 @@
             logd("setUiccApplicationsEnabled subId= " + subscriptionId + " enable " + enabled);
         }
         try {
-            ISub iSub = ISub.Stub.asInterface(
-                    TelephonyFrameworkInitializer
-                            .getTelephonyServiceManager()
-                            .getSubscriptionServiceRegisterer()
-                            .get());
+            ISub iSub = TelephonyManager.getSubscriptionService();
             if (iSub != null) {
                 iSub.setUiccApplicationsEnabled(enabled, subscriptionId);
             }
@@ -3715,11 +3700,7 @@
             logd("canDisablePhysicalSubscription");
         }
         try {
-            ISub iSub = ISub.Stub.asInterface(
-                    TelephonyFrameworkInitializer
-                            .getTelephonyServiceManager()
-                            .getSubscriptionServiceRegisterer()
-                            .get());
+            ISub iSub = TelephonyManager.getSubscriptionService();
             if (iSub != null) {
                 return iSub.canDisablePhysicalSubscription();
             }
@@ -3843,10 +3824,15 @@
     }
 
     /**
-     * DO NOT USE.
-     * This API is designed for features that are not finished at this point. Do not call this API.
+     * Get the active subscription id by logical SIM slot index.
+     *
+     * @param slotIndex The logical SIM slot index.
+     * @return The active subscription id.
+     *
+     * @throws IllegalArgumentException if the provided slot index is invalid.
+     * @throws SecurityException if callers do not hold the required permission.
+     *
      * @hide
-     * TODO b/135547512: further clean up
      */
     @SystemApi
     @RequiresPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
diff --git a/telephony/java/com/android/internal/telephony/ISub.aidl b/telephony/java/com/android/internal/telephony/ISub.aidl
index af4edc4..6a5380d 100644
--- a/telephony/java/com/android/internal/telephony/ISub.aidl
+++ b/telephony/java/com/android/internal/telephony/ISub.aidl
@@ -236,8 +236,6 @@
 
     int getSlotIndex(int subId);
 
-    int[] getSubIds(int slotIndex);
-
     int getSubId(int slotIndex);
 
     int getDefaultSubId();
@@ -267,8 +265,6 @@
     String getSubscriptionProperty(int subId, String propKey, String callingPackage,
             String callingFeatureId);
 
-    boolean setSubscriptionEnabled(boolean enable, int subId);
-
     boolean isSubscriptionEnabled(int subId);
 
     int getEnabledSubscriptionId(int slotIndex);
@@ -279,7 +275,7 @@
 
     boolean canDisablePhysicalSubscription();
 
-    int setUiccApplicationsEnabled(boolean enabled, int subscriptionId);
+    void setUiccApplicationsEnabled(boolean enabled, int subscriptionId);
 
     int setDeviceToDeviceStatusSharing(int sharing, int subId);
 
diff --git a/tests/vcn/java/com/android/server/vcn/TelephonySubscriptionTrackerTest.java b/tests/vcn/java/com/android/server/vcn/TelephonySubscriptionTrackerTest.java
index 965b073..34f884b 100644
--- a/tests/vcn/java/com/android/server/vcn/TelephonySubscriptionTrackerTest.java
+++ b/tests/vcn/java/com/android/server/vcn/TelephonySubscriptionTrackerTest.java
@@ -19,9 +19,6 @@
 import static android.net.NetworkCapabilities.TRANSPORT_CELLULAR;
 import static android.net.NetworkCapabilities.TRANSPORT_WIFI;
 import static android.net.vcn.VcnManager.VCN_RESTRICTED_TRANSPORTS_INT_ARRAY_KEY;
-import static android.telephony.CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED;
-import static android.telephony.CarrierConfigManager.EXTRA_SLOT_INDEX;
-import static android.telephony.CarrierConfigManager.EXTRA_SUBSCRIPTION_INDEX;
 import static android.telephony.SubscriptionManager.INVALID_SIM_SLOT_INDEX;
 import static android.telephony.SubscriptionManager.INVALID_SUBSCRIPTION_ID;
 import static android.telephony.TelephonyCallback.ActiveDataSubscriptionIdListener;
@@ -143,6 +140,8 @@
     @NonNull private TelephonySubscriptionTrackerCallback mCallback;
     @NonNull private TelephonySubscriptionTracker mTelephonySubscriptionTracker;
 
+    @NonNull private CarrierConfigManager.CarrierConfigChangeListener mCarrierConfigChangeListener;
+
     public TelephonySubscriptionTrackerTest() {
         mContext = mock(Context.class);
         mTestLooper = new TestLooper();
@@ -173,7 +172,7 @@
                 .getSystemService(Context.CARRIER_CONFIG_SERVICE);
         doReturn(TEST_CARRIER_CONFIG)
                 .when(mCarrierConfigManager)
-                .getConfigForSubId(eq(TEST_SUBSCRIPTION_ID_1));
+                .getConfigForSubId(eq(TEST_SUBSCRIPTION_ID_1), any());
 
         // subId 1, 2 are in same subGrp, only subId 1 is active
         doReturn(TEST_PARCEL_UUID).when(TEST_SUBINFO_1).getGroupUuid();
@@ -189,9 +188,15 @@
         doReturn(2).when(mTelephonyManager).getActiveModemCount();
 
         mCallback = mock(TelephonySubscriptionTrackerCallback.class);
+        // Capture CarrierConfigChangeListener to emulate the carrier config change notification
+        ArgumentCaptor<CarrierConfigManager.CarrierConfigChangeListener> listenerArgumentCaptor =
+                ArgumentCaptor.forClass(CarrierConfigManager.CarrierConfigChangeListener.class);
         mTelephonySubscriptionTracker =
                 new TelephonySubscriptionTracker(mContext, mHandler, mCallback, mDeps);
         mTelephonySubscriptionTracker.register();
+        verify(mCarrierConfigManager).registerCarrierConfigChangeListener(any(),
+                listenerArgumentCaptor.capture());
+        mCarrierConfigChangeListener = listenerArgumentCaptor.getAllValues().get(0);
 
         doReturn(true).when(mDeps).isConfigForIdentifiedCarrier(any());
         doReturn(Arrays.asList(TEST_SUBINFO_1, TEST_SUBINFO_2))
@@ -239,14 +244,11 @@
         return intent;
     }
 
-    private Intent buildTestBroadcastIntent(boolean hasValidSubscription) {
-        Intent intent = new Intent(ACTION_CARRIER_CONFIG_CHANGED);
-        intent.putExtra(EXTRA_SLOT_INDEX, TEST_SIM_SLOT_INDEX);
-        intent.putExtra(
-                EXTRA_SUBSCRIPTION_INDEX,
-                hasValidSubscription ? TEST_SUBSCRIPTION_ID_1 : INVALID_SUBSCRIPTION_ID);
-
-        return intent;
+    private void sendCarrierConfigChange(boolean hasValidSubscription) {
+        mCarrierConfigChangeListener.onCarrierConfigChanged(
+                TEST_SIM_SLOT_INDEX,
+                hasValidSubscription ? TEST_SUBSCRIPTION_ID_1 : INVALID_SUBSCRIPTION_ID,
+                TelephonyManager.UNKNOWN_CARRIER_ID, TelephonyManager.UNKNOWN_CARRIER_ID);
     }
 
     private TelephonySubscriptionSnapshot buildExpectedSnapshot(
@@ -302,14 +304,15 @@
                         any(),
                         eq(mHandler));
         final IntentFilter filter = getIntentFilter();
-        assertEquals(2, filter.countActions());
-        assertTrue(filter.hasAction(ACTION_CARRIER_CONFIG_CHANGED));
+        assertEquals(1, filter.countActions());
         assertTrue(filter.hasAction(ACTION_MULTI_SIM_CONFIG_CHANGED));
 
         verify(mSubscriptionManager)
                 .addOnSubscriptionsChangedListener(any(HandlerExecutor.class), any());
         assertNotNull(getOnSubscriptionsChangedListener());
 
+        verify(mCarrierConfigManager).registerCarrierConfigChangeListener(any(), any());
+
         verify(mTelephonyManager, times(2))
                 .registerCarrierPrivilegesCallback(anyInt(), any(HandlerExecutor.class), any());
         verify(mTelephonyManager)
@@ -442,7 +445,7 @@
 
     @Test
     public void testReceiveBroadcast_ConfigReadyWithSubscriptions() throws Exception {
-        mTelephonySubscriptionTracker.onReceive(mContext, buildTestBroadcastIntent(true));
+        sendCarrierConfigChange(true /* hasValidSubscription */);
         mTestLooper.dispatchAll();
 
         verify(mCallback).onNewSnapshot(eq(buildExpectedSnapshot(TEST_PRIVILEGED_PACKAGES)));
@@ -454,7 +457,7 @@
                 .when(mSubscriptionManager)
                 .getAllSubscriptionInfoList();
 
-        mTelephonySubscriptionTracker.onReceive(mContext, buildTestBroadcastIntent(true));
+        sendCarrierConfigChange(true /* hasValidSubscription */);
         mTestLooper.dispatchAll();
 
         // Expect an empty snapshot
@@ -465,7 +468,7 @@
     public void testReceiveBroadcast_SlotCleared() throws Exception {
         setupReadySubIds();
 
-        mTelephonySubscriptionTracker.onReceive(mContext, buildTestBroadcastIntent(false));
+        sendCarrierConfigChange(false /* hasValidSubscription */);
         mTestLooper.dispatchAll();
 
         verifyNoActiveSubscriptions();
@@ -476,7 +479,7 @@
     public void testReceiveBroadcast_ConfigNotReady() throws Exception {
         doReturn(false).when(mDeps).isConfigForIdentifiedCarrier(any());
 
-        mTelephonySubscriptionTracker.onReceive(mContext, buildTestBroadcastIntent(true));
+        sendCarrierConfigChange(true /* hasValidSubscription */);
         mTestLooper.dispatchAll();
 
         // No interactions expected; config was not loaded
@@ -485,21 +488,21 @@
 
     @Test
     public void testSubscriptionsClearedAfterValidTriggersCallbacks() throws Exception {
-        mTelephonySubscriptionTracker.onReceive(mContext, buildTestBroadcastIntent(true));
+        sendCarrierConfigChange(true /* hasValidSubscription */);
         mTestLooper.dispatchAll();
         verify(mCallback).onNewSnapshot(eq(buildExpectedSnapshot(TEST_PRIVILEGED_PACKAGES)));
         assertNotNull(
                 mTelephonySubscriptionTracker.getReadySubIdsBySlotId().get(TEST_SIM_SLOT_INDEX));
 
         doReturn(Collections.emptyList()).when(mSubscriptionManager).getAllSubscriptionInfoList();
-        mTelephonySubscriptionTracker.onReceive(mContext, buildTestBroadcastIntent(true));
+        sendCarrierConfigChange(true /* hasValidSubscription */);
         mTestLooper.dispatchAll();
         verify(mCallback).onNewSnapshot(eq(buildExpectedSnapshot(emptyMap(), emptyMap())));
     }
 
     @Test
     public void testCarrierConfigUpdatedAfterValidTriggersCallbacks() throws Exception {
-        mTelephonySubscriptionTracker.onReceive(mContext, buildTestBroadcastIntent(true));
+        sendCarrierConfigChange(true /* hasValidSubscription */);
         mTestLooper.dispatchAll();
         verify(mCallback).onNewSnapshot(eq(buildExpectedSnapshot(TEST_PRIVILEGED_PACKAGES)));
         reset(mCallback);
@@ -510,12 +513,12 @@
                 new int[] {TRANSPORT_WIFI, TRANSPORT_CELLULAR});
         doReturn(updatedConfig)
                 .when(mCarrierConfigManager)
-                .getConfigForSubId(eq(TEST_SUBSCRIPTION_ID_1));
+                .getConfigForSubId(eq(TEST_SUBSCRIPTION_ID_1), any());
 
         Map<Integer, PersistableBundleWrapper> subIdToCarrierConfigMap = new HashMap<>();
         subIdToCarrierConfigMap.put(
                 TEST_SUBSCRIPTION_ID_1, new PersistableBundleWrapper(updatedConfig));
-        mTelephonySubscriptionTracker.onReceive(mContext, buildTestBroadcastIntent(true));
+        sendCarrierConfigChange(true /* hasValidSubscription */);
         mTestLooper.dispatchAll();
 
         verify(mCallback)
@@ -530,13 +533,13 @@
 
     @Test
     public void testSlotClearedAfterValidTriggersCallbacks() throws Exception {
-        mTelephonySubscriptionTracker.onReceive(mContext, buildTestBroadcastIntent(true));
+        sendCarrierConfigChange(true /* hasValidSubscription */);
         mTestLooper.dispatchAll();
         verify(mCallback).onNewSnapshot(eq(buildExpectedSnapshot(TEST_PRIVILEGED_PACKAGES)));
         assertNotNull(
                 mTelephonySubscriptionTracker.getReadySubIdsBySlotId().get(TEST_SIM_SLOT_INDEX));
 
-        mTelephonySubscriptionTracker.onReceive(mContext, buildTestBroadcastIntent(false));
+        sendCarrierConfigChange(false /* hasValidSubscription */);
         mTestLooper.dispatchAll();
         verify(mCallback)
                 .onNewSnapshot(