Fix VCN crash when retrieving carrier config while phone is gone

This CL calls CarrierConfigManager.getCarrierConfigSubset instead of
getConfigForSubId to guard against crashing when phone process has gone.

The former method is designed for system components to retrieve carrier
configs with consideration of phone process may be gone (e.g. during
rebooting from previous crash).

Bug: 319791612
Test: atest TelephonySubscriptionTrackerTest
Change-Id: I784610b243db2a666c1fe89b1438950a2f6a1478
diff --git a/services/core/java/com/android/server/vcn/TelephonySubscriptionTracker.java b/services/core/java/com/android/server/vcn/TelephonySubscriptionTracker.java
index 099c9ae..17f5e95 100644
--- a/services/core/java/com/android/server/vcn/TelephonySubscriptionTracker.java
+++ b/services/core/java/com/android/server/vcn/TelephonySubscriptionTracker.java
@@ -44,6 +44,7 @@
 
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.annotations.VisibleForTesting.Visibility;
+import com.android.internal.telephony.flags.Flags;
 import com.android.internal.util.IndentingPrintWriter;
 import com.android.server.vcn.util.PersistableBundleUtils.PersistableBundleWrapper;
 
@@ -318,8 +319,12 @@
 
         if (SubscriptionManager.isValidSubscriptionId(subId)) {
             // Get only configs as needed to save memory.
-            final PersistableBundle carrierConfig = mCarrierConfigManager.getConfigForSubId(subId,
-                    VcnManager.VCN_RELATED_CARRIER_CONFIG_KEYS);
+            final PersistableBundle carrierConfig =
+                    Flags.fixCrashOnGettingConfigWhenPhoneIsGone()
+                            ? CarrierConfigManager.getCarrierConfigSubset(mContext, subId,
+                                    VcnManager.VCN_RELATED_CARRIER_CONFIG_KEYS)
+                            : mCarrierConfigManager.getConfigForSubId(subId,
+                                    VcnManager.VCN_RELATED_CARRIER_CONFIG_KEYS);
             if (mDeps.isConfigForIdentifiedCarrier(carrierConfig)) {
                 mReadySubIdsBySlotId.put(slotId, subId);
 
diff --git a/tests/vcn/Android.bp b/tests/vcn/Android.bp
index 228520e..308889f 100644
--- a/tests/vcn/Android.bp
+++ b/tests/vcn/Android.bp
@@ -30,6 +30,7 @@
         "platform-test-annotations",
         "services.core",
         "service-connectivity-tiramisu-pre-jarjar",
+        "flag-junit",
     ],
     libs: [
         "android.test.runner",
diff --git a/tests/vcn/java/com/android/server/vcn/TelephonySubscriptionTrackerTest.java b/tests/vcn/java/com/android/server/vcn/TelephonySubscriptionTrackerTest.java
index 34f884b..887630b 100644
--- a/tests/vcn/java/com/android/server/vcn/TelephonySubscriptionTrackerTest.java
+++ b/tests/vcn/java/com/android/server/vcn/TelephonySubscriptionTrackerTest.java
@@ -38,6 +38,7 @@
 import static org.mockito.ArgumentMatchers.eq;
 import static org.mockito.Mockito.atLeastOnce;
 import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.doThrow;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.reset;
 import static org.mockito.Mockito.times;
@@ -58,6 +59,7 @@
 import android.os.ParcelUuid;
 import android.os.PersistableBundle;
 import android.os.test.TestLooper;
+import android.platform.test.flag.junit.SetFlagsRule;
 import android.telephony.CarrierConfigManager;
 import android.telephony.SubscriptionInfo;
 import android.telephony.SubscriptionManager;
@@ -71,7 +73,10 @@
 import androidx.test.filters.SmallTest;
 import androidx.test.runner.AndroidJUnit4;
 
+import com.android.internal.telephony.flags.Flags;
+
 import org.junit.Before;
+import org.junit.Rule;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.mockito.ArgumentCaptor;
@@ -128,6 +133,9 @@
         TEST_SUBID_TO_CARRIER_CONFIG_MAP = Collections.unmodifiableMap(subIdToCarrierConfigMap);
     }
 
+    @Rule public final SetFlagsRule mSetFlagsRule = new SetFlagsRule();
+
+
     @NonNull private final Context mContext;
     @NonNull private final TestLooper mTestLooper;
     @NonNull private final Handler mHandler;
@@ -185,6 +193,7 @@
 
     @Before
     public void setUp() throws Exception {
+        mSetFlagsRule.enableFlags(Flags.FLAG_FIX_CRASH_ON_GETTING_CONFIG_WHEN_PHONE_IS_GONE);
         doReturn(2).when(mTelephonyManager).getActiveModemCount();
 
         mCallback = mock(TelephonySubscriptionTrackerCallback.class);
@@ -594,4 +603,14 @@
                 new ArraySet<>(Arrays.asList(TEST_SUBSCRIPTION_ID_1, TEST_SUBSCRIPTION_ID_2)),
                 snapshot.getAllSubIdsInGroup(TEST_PARCEL_UUID));
     }
+
+    @Test
+    public void testCarrierConfigChangeWhenPhoneIsGoneShouldNotCrash() throws Exception {
+        doThrow(new IllegalStateException("Carrier config loader is not available."))
+                .when(mCarrierConfigManager)
+                .getConfigForSubId(eq(TEST_SUBSCRIPTION_ID_1), any());
+
+        sendCarrierConfigChange(true /* hasValidSubscription */);
+        mTestLooper.dispatchAll();
+    }
 }