diff --git a/src/com/android/phone/CarrierConfigLoader.java b/src/com/android/phone/CarrierConfigLoader.java
index 4ff7316..e729d28 100644
--- a/src/com/android/phone/CarrierConfigLoader.java
+++ b/src/com/android/phone/CarrierConfigLoader.java
@@ -36,6 +36,7 @@
 import android.os.Bundle;
 import android.os.Handler;
 import android.os.IBinder;
+import android.os.Looper;
 import android.os.Message;
 import android.os.PersistableBundle;
 import android.os.Process;
@@ -55,6 +56,7 @@
 import android.util.LocalLog;
 import android.util.Log;
 
+import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.telephony.ICarrierConfigLoader;
 import com.android.internal.telephony.IccCardConstants;
 import com.android.internal.telephony.Phone;
@@ -201,6 +203,10 @@
     // 3. clearing config (e.g. due to sim removal)
     // 4. encountering bind or IPC error
     private class ConfigHandler extends Handler {
+        ConfigHandler(@NonNull Looper looper) {
+            super(looper);
+        }
+
         @Override
         public void handleMessage(Message msg) {
             final int phoneId = msg.arg1;
@@ -287,7 +293,7 @@
                         } else {
                             // Put a stub bundle in place so that the rest of the logic continues
                             // smoothly.
-                            mConfigFromDefaultApp[phoneId] = new PersistableBundle();
+                            mConfigFromDefaultApp[phoneId] = PersistableBundle.EMPTY;
                             // Send broadcast if bind fails.
                             notifySubscriptionInfoUpdater(phoneId);
                             // TODO: We *must* call unbindService even if bindService returns false.
@@ -372,7 +378,7 @@
                         broadcastConfigChangedIntent(phoneId);
                     }
                     // Put a stub bundle in place so that the rest of the logic continues smoothly.
-                    mConfigFromDefaultApp[phoneId] = new PersistableBundle();
+                    mConfigFromDefaultApp[phoneId] = PersistableBundle.EMPTY;
                     notifySubscriptionInfoUpdater(phoneId);
                     break;
                 }
@@ -419,7 +425,7 @@
                         } else {
                             // Put a stub bundle in place so that the rest of the logic continues
                             // smoothly.
-                            mConfigFromCarrierApp[phoneId] = new PersistableBundle();
+                            mConfigFromCarrierApp[phoneId] = PersistableBundle.EMPTY;
                             // Send broadcast if bind fails.
                             broadcastConfigChangedIntent(phoneId);
                             loge("Bind to carrier app: " + carrierPackageName + " fails");
@@ -504,7 +510,7 @@
                         broadcastConfigChangedIntent(phoneId);
                     }
                     // Put a stub bundle in place so that the rest of the logic continues smoothly.
-                    mConfigFromCarrierApp[phoneId] = new PersistableBundle();
+                    mConfigFromCarrierApp[phoneId] = PersistableBundle.EMPTY;
                     notifySubscriptionInfoUpdater(phoneId);
                     break;
                 }
@@ -666,11 +672,13 @@
      * Constructs a CarrierConfigLoader, registers it as a service, and registers a broadcast
      * receiver for relevant events.
      */
-    private CarrierConfigLoader(Context context) {
+    @VisibleForTesting
+    /* package */ CarrierConfigLoader(Context context,
+            SubscriptionInfoUpdater subscriptionInfoUpdater, @NonNull Looper looper) {
         mContext = context;
         mPlatformCarrierConfigPackage =
                 mContext.getString(R.string.platform_carrier_config_package);
-        mHandler = new ConfigHandler();
+        mHandler = new ConfigHandler(looper);
 
         IntentFilter bootFilter = new IntentFilter();
         bootFilter.addAction(Intent.ACTION_BOOT_COMPLETED);
@@ -690,7 +698,7 @@
         mConfigFromCarrierApp = new PersistableBundle[numPhones];
         mPersistentOverrideConfigs = new PersistableBundle[numPhones];
         mOverrideConfigs = new PersistableBundle[numPhones];
-        mNoSimConfig = new PersistableBundle();
+        mNoSimConfig = PersistableBundle.EMPTY;
         mServiceConnection = new CarrierServiceConnection[numPhones];
         mServiceBound = new boolean[numPhones];
         mHasSentConfigChange = new boolean[numPhones];
@@ -701,7 +709,7 @@
         TelephonyFrameworkInitializer
                 .getTelephonyServiceManager().getCarrierConfigServiceRegisterer().register(this);
         logd("CarrierConfigLoader has started");
-        mSubscriptionInfoUpdater = PhoneFactory.getSubscriptionInfoUpdater();
+        mSubscriptionInfoUpdater = subscriptionInfoUpdater;
         mHandler.sendEmptyMessage(EVENT_CHECK_SYSTEM_UPDATE);
     }
 
@@ -710,11 +718,11 @@
      *
      * This is only done once, at startup, from {@link com.android.phone.PhoneApp#onCreate}.
      */
-    /* package */
-    static CarrierConfigLoader init(Context context) {
+    /* package */ static CarrierConfigLoader init(Context context) {
         synchronized (CarrierConfigLoader.class) {
             if (sInstance == null) {
-                sInstance = new CarrierConfigLoader(context);
+                sInstance = new CarrierConfigLoader(context,
+                        PhoneFactory.getSubscriptionInfoUpdater(), Looper.myLooper());
             } else {
                 Log.wtf(LOG_TAG, "init() called multiple times!  sInstance = " + sInstance);
             }
@@ -722,7 +730,8 @@
         }
     }
 
-    private void clearConfigForPhone(int phoneId, boolean fetchNoSimConfig) {
+    @VisibleForTesting
+    /* package */ void clearConfigForPhone(int phoneId, boolean fetchNoSimConfig) {
         /* Ignore clear configuration request if device is being shutdown. */
         Phone phone = PhoneFactory.getPhone(phoneId);
         if (phone != null) {
@@ -759,7 +768,7 @@
         }
 
         if (configToSend == null) {
-            configToSend = new PersistableBundle();
+            configToSend = PersistableBundle.EMPTY;
         }
 
         // mOverrideConfigs is for testing. And it will override current configs.
@@ -844,7 +853,8 @@
         }
     }
 
-    private CarrierIdentifier getCarrierIdentifierForPhoneId(int phoneId) {
+    @VisibleForTesting
+    /* package */ CarrierIdentifier getCarrierIdentifierForPhoneId(int phoneId) {
         String mcc = "";
         String mnc = "";
         String imsi = "";
@@ -1000,12 +1010,14 @@
         }
     }
 
-    private void saveConfigToXml(String packageName, @NonNull String extraString, int phoneId,
+    @VisibleForTesting
+    /* package */ void saveConfigToXml(String packageName, @NonNull String extraString, int phoneId,
             CarrierIdentifier carrierId, PersistableBundle config) {
         saveConfigToXml(packageName, extraString, phoneId, carrierId, config, false);
     }
 
-    private void saveNoSimConfigToXml(String packageName, PersistableBundle config) {
+    @VisibleForTesting
+    /* package */ void saveNoSimConfigToXml(String packageName, PersistableBundle config) {
         saveConfigToXml(packageName, "", -1, null, config, true);
     }
 
@@ -1176,7 +1188,7 @@
             String callingFeatureId) {
         if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(mContext, subId, callingPackage,
                 callingFeatureId, "getCarrierConfig")) {
-            return new PersistableBundle();
+            return PersistableBundle.EMPTY;
         }
 
         int phoneId = SubscriptionManager.getPhoneId(subId);
@@ -1253,7 +1265,7 @@
     private void overrideConfig(@NonNull PersistableBundle[] currentOverrides, int phoneId,
             @Nullable PersistableBundle overrides) {
         if (overrides == null) {
-            currentOverrides[phoneId] = new PersistableBundle();
+            currentOverrides[phoneId] = PersistableBundle.EMPTY;
         } else if (currentOverrides[phoneId] == null) {
             currentOverrides[phoneId] = overrides;
         } else {
@@ -1315,6 +1327,31 @@
         return mPlatformCarrierConfigPackage;
     }
 
+    @VisibleForTesting
+    /* package */ Handler getHandler() {
+        return mHandler;
+    }
+
+    @VisibleForTesting
+    /* package */ PersistableBundle getConfigFromDefaultApp(int phoneId) {
+        return mConfigFromDefaultApp[phoneId];
+    }
+
+    @VisibleForTesting
+    /* package */ PersistableBundle getConfigFromCarrierApp(int phoneId) {
+        return mConfigFromCarrierApp[phoneId];
+    }
+
+    @VisibleForTesting
+     /* package */ PersistableBundle getNoSimConfig() {
+        return mNoSimConfig;
+    }
+
+    @VisibleForTesting
+    /* package */ PersistableBundle getOverrideConfig(int phoneId) {
+        return mOverrideConfigs[phoneId];
+    }
+
     private void unbindIfBound(Context context, CarrierServiceConnection conn,
             int phoneId) {
         if (mServiceBound[phoneId]) {
diff --git a/tests/src/com/android/TestContext.java b/tests/src/com/android/TestContext.java
index 9d712d3..fc5ee4c 100644
--- a/tests/src/com/android/TestContext.java
+++ b/tests/src/com/android/TestContext.java
@@ -24,6 +24,8 @@
 import android.content.Context;
 import android.content.Intent;
 import android.content.IntentFilter;
+import android.content.pm.PackageManager;
+import android.os.Binder;
 import android.os.Handler;
 import android.os.PersistableBundle;
 import android.telecom.TelecomManager;
@@ -32,16 +34,22 @@
 import android.telephony.TelephonyManager;
 import android.telephony.ims.ImsManager;
 import android.test.mock.MockContext;
+import android.util.Log;
 import android.util.SparseArray;
 
 import org.mockito.Mock;
 import org.mockito.MockitoAnnotations;
 import org.mockito.stubbing.Answer;
 
+import java.util.HashSet;
 import java.util.concurrent.Executor;
 
 public class TestContext extends MockContext {
 
+    private static final String TAG = "TestContext";
+    // Stub used to grant all permissions
+    public static final String STUB_PERMISSION_ENABLE_ALL = "stub_permission_enable_all";
+
     @Mock CarrierConfigManager mMockCarrierConfigManager;
     @Mock TelecomManager mMockTelecomManager;
     @Mock TelephonyManager mMockTelephonyManager;
@@ -50,6 +58,8 @@
 
     private SparseArray<PersistableBundle> mCarrierConfigs = new SparseArray<>();
 
+    private final HashSet<String> mPermissionTable = new HashSet<>();
+
     public TestContext() {
         MockitoAnnotations.initMocks(this);
         doAnswer((Answer<PersistableBundle>) invocation -> {
@@ -161,4 +171,67 @@
         }
         return b;
     }
+
+    @Override
+    public void enforceCallingOrSelfPermission(String permission, String message) {
+        if (checkCallingOrSelfPermission(permission) != PackageManager.PERMISSION_GRANTED) {
+            throw new SecurityException(permission + " denied: " + message);
+        }
+    }
+
+    @Override
+    public void enforcePermission(String permission, int pid, int uid, String message) {
+        enforceCallingOrSelfPermission(permission, message);
+    }
+
+    @Override
+    public void enforceCallingPermission(String permission, String message) {
+        enforceCallingOrSelfPermission(permission, message);
+    }
+
+    @Override
+    public int checkCallingOrSelfPermission(String permission) {
+        return checkPermission(permission, Binder.getCallingPid(), Binder.getCallingUid());
+    }
+
+    @Override
+    public int checkPermission(String permission, int pid, int uid) {
+        synchronized (mPermissionTable) {
+            if (mPermissionTable.contains(permission)
+                    || mPermissionTable.contains(STUB_PERMISSION_ENABLE_ALL)) {
+                logd("checkCallingOrSelfPermission: " + permission + " return GRANTED");
+                return PackageManager.PERMISSION_GRANTED;
+            } else {
+                logd("checkCallingOrSelfPermission: " + permission + " return DENIED");
+                return PackageManager.PERMISSION_DENIED;
+            }
+        }
+    }
+
+    public void grantPermission(String permission) {
+        synchronized (mPermissionTable) {
+            if (mPermissionTable != null && permission != null) {
+                mPermissionTable.remove(STUB_PERMISSION_ENABLE_ALL);
+                mPermissionTable.add(permission);
+            }
+        }
+    }
+
+    public void revokePermission(String permission) {
+        synchronized (mPermissionTable) {
+            if (mPermissionTable != null && permission != null) {
+                mPermissionTable.remove(permission);
+            }
+        }
+    }
+
+    public void revokeAllPermissions() {
+        synchronized (mPermissionTable) {
+            mPermissionTable.clear();
+        }
+    }
+
+    private static void logd(String s) {
+        Log.d(TAG, s);
+    }
 }
diff --git a/tests/src/com/android/phone/CarrierConfigLoaderTest.java b/tests/src/com/android/phone/CarrierConfigLoaderTest.java
new file mode 100644
index 0000000..7fd9069
--- /dev/null
+++ b/tests/src/com/android/phone/CarrierConfigLoaderTest.java
@@ -0,0 +1,381 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.phone;
+
+import static com.android.TestContext.STUB_PERMISSION_ENABLE_ALL;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.junit.Assert.assertThrows;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.ArgumentMatchers.anyString;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.ArgumentMatchers.nullable;
+import static org.mockito.Mockito.doNothing;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.verify;
+
+import android.content.Intent;
+import android.content.SharedPreferences;
+import android.content.pm.PackageInfo;
+import android.content.pm.PackageManager;
+import android.content.res.Resources;
+import android.os.Build;
+import android.os.Handler;
+import android.os.HandlerThread;
+import android.os.Message;
+import android.os.PersistableBundle;
+import android.os.UserHandle;
+import android.service.carrier.CarrierIdentifier;
+import android.telephony.CarrierConfigManager;
+import android.telephony.SubscriptionManager;
+import android.telephony.TelephonyManager;
+import android.testing.TestableLooper;
+
+import androidx.test.InstrumentationRegistry;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+
+import com.android.TelephonyTestBase;
+import com.android.internal.telephony.IccCardConstants;
+import com.android.internal.telephony.SubscriptionInfoUpdater;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Ignore;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.Mockito;
+
+import java.io.FileDescriptor;
+import java.io.PrintWriter;
+import java.io.StringWriter;
+import java.util.List;
+
+/**
+ * Unit Test for CarrierConfigLoader.
+ */
+@RunWith(AndroidJUnit4.class)
+public class CarrierConfigLoaderTest extends TelephonyTestBase {
+
+    private static final int DEFAULT_PHONE_ID = 0;
+    private static final int DEFAULT_SUB_ID = SubscriptionManager.getDefaultSubscriptionId();
+    private static final String PLATFORM_CARRIER_CONFIG_PACKAGE = "com.android.carrierconfig";
+    private static final long PLATFORM_CARRIER_CONFIG_PACKAGE_VERSION_CODE = 1;
+    private static final String CARRIER_CONFIG_EXAMPLE_KEY =
+            CarrierConfigManager.KEY_CARRIER_USSD_METHOD_INT;
+    private static final int CARRIER_CONFIG_EXAMPLE_VALUE =
+            CarrierConfigManager.USSD_OVER_CS_PREFERRED;
+
+    @Mock Resources mResources;
+    @Mock PackageManager mPackageManager;
+    @Mock PackageInfo mPackageInfo;
+    @Mock SubscriptionInfoUpdater mSubscriptionInfoUpdater;
+    @Mock SharedPreferences mSharedPreferences;
+
+    private TelephonyManager mTelephonyManager;
+    private CarrierConfigLoader mCarrierConfigLoader;
+    private Handler mHandler;
+    private HandlerThread mHandlerThread;
+    private TestableLooper mTestableLooper;
+
+    @Before
+    public void setUp() throws Exception {
+        super.setUp();
+
+        doReturn(mSharedPreferences).when(mContext).getSharedPreferences(anyString(), anyInt());
+        doReturn(Build.FINGERPRINT).when(mSharedPreferences).getString(eq("build_fingerprint"),
+                any());
+        doReturn(mPackageManager).when(mContext).getPackageManager();
+        doReturn(mResources).when(mContext).getResources();
+        doReturn(InstrumentationRegistry.getTargetContext().getFilesDir()).when(
+                mContext).getFilesDir();
+        doReturn(PLATFORM_CARRIER_CONFIG_PACKAGE).when(mResources).getString(
+                eq(R.string.platform_carrier_config_package));
+        mTelephonyManager = mContext.getSystemService(TelephonyManager.class);
+        doReturn(1).when(mTelephonyManager).getSupportedModemCount();
+        doReturn(1).when(mTelephonyManager).getActiveModemCount();
+        doReturn("spn").when(mTelephonyManager).getSimOperatorNameForPhone(anyInt());
+        doReturn("310260").when(mTelephonyManager).getSimOperatorNumericForPhone(anyInt());
+        doReturn(mPackageInfo).when(mPackageManager).getPackageInfo(
+                eq(PLATFORM_CARRIER_CONFIG_PACKAGE), eq(0) /*flags*/);
+        doReturn(PLATFORM_CARRIER_CONFIG_PACKAGE_VERSION_CODE).when(
+                mPackageInfo).getLongVersionCode();
+
+        mHandlerThread = new HandlerThread("CarrierConfigLoaderTest");
+        mHandlerThread.start();
+
+        mTestableLooper = new TestableLooper(mHandlerThread.getLooper());
+        mCarrierConfigLoader = new CarrierConfigLoader(mContext, mSubscriptionInfoUpdater,
+                mTestableLooper.getLooper());
+        mHandler = mCarrierConfigLoader.getHandler();
+
+        // Clear all configs to have the same starting point.
+        mCarrierConfigLoader.clearConfigForPhone(DEFAULT_PHONE_ID, false);
+    }
+
+    @After
+    public void tearDown() throws Exception {
+        mContext.revokeAllPermissions();
+        mTestableLooper.destroy();
+        super.tearDown();
+    }
+
+    /**
+     * Verifies that SecurityException should throw when call #updateConfigForPhoneId() without
+     * MODIFY_PHONE_STATE permission.
+     */
+    @Test
+    public void testUpdateConfigForPhoneId_noPermission() throws Exception {
+        assertThrows(SecurityException.class,
+                () -> mCarrierConfigLoader.updateConfigForPhoneId(DEFAULT_PHONE_ID,
+                        IccCardConstants.INTENT_VALUE_ICC_ABSENT));
+    }
+
+    /**
+     * Verifies that when call #updateConfigForPhoneId() with SIM absence, both carrier config from
+     * default app and carrier should be cleared but no-sim config should be loaded.
+     */
+    @Test
+    public void testUpdateConfigForPhoneId_simAbsent() throws Exception {
+        // Bypass case if default subId is not supported by device to reduce flakiness
+        if (!SubscriptionManager.isValidPhoneId(SubscriptionManager.getPhoneId(DEFAULT_SUB_ID))) {
+            return;
+        }
+        mContext.grantPermission(STUB_PERMISSION_ENABLE_ALL);
+        doNothing().when(mContext).sendBroadcastAsUser(any(Intent.class), any(UserHandle.class));
+
+        // Prepare a cached config to fetch from xml
+        PersistableBundle config = getTestConfig();
+        mCarrierConfigLoader.saveNoSimConfigToXml(PLATFORM_CARRIER_CONFIG_PACKAGE, config);
+        mCarrierConfigLoader.updateConfigForPhoneId(DEFAULT_PHONE_ID,
+                IccCardConstants.INTENT_VALUE_ICC_ABSENT);
+        mTestableLooper.processAllMessages();
+
+        assertThat(mCarrierConfigLoader.getConfigFromDefaultApp(DEFAULT_PHONE_ID)).isNull();
+        assertThat(mCarrierConfigLoader.getConfigFromCarrierApp(DEFAULT_PHONE_ID)).isNull();
+        assertThat(mCarrierConfigLoader.getNoSimConfig().getInt(CARRIER_CONFIG_EXAMPLE_KEY))
+                .isEqualTo(CARRIER_CONFIG_EXAMPLE_VALUE);
+        verify(mContext).sendBroadcastAsUser(any(Intent.class), any(UserHandle.class));
+    }
+
+    /**
+     * Verifies that with cached config in XML, calling #updateConfigForPhoneId() with SIM loaded
+     * will return the right config in the XML.
+     */
+    @Test
+    public void testUpdateConfigForPhoneId_simLoaded_withCachedConfigInXml() throws Exception {
+        // Bypass case if default subId is not supported by device to reduce flakiness
+        if (!SubscriptionManager.isValidPhoneId(SubscriptionManager.getPhoneId(DEFAULT_SUB_ID))) {
+            return;
+        }
+        mContext.grantPermission(STUB_PERMISSION_ENABLE_ALL);
+
+        // Prepare to make sure we can save the config into the XML file which used as cache
+        List<String> carrierPackages = List.of(PLATFORM_CARRIER_CONFIG_PACKAGE);
+        doReturn(carrierPackages).when(mTelephonyManager).getCarrierPackageNamesForIntentAndPhone(
+                nullable(Intent.class), anyInt());
+
+        // Save the sample config into the XML file
+        PersistableBundle config = getTestConfig();
+        CarrierIdentifier carrierId = mCarrierConfigLoader.getCarrierIdentifierForPhoneId(
+                DEFAULT_PHONE_ID);
+        mCarrierConfigLoader.saveConfigToXml(PLATFORM_CARRIER_CONFIG_PACKAGE, "",
+                DEFAULT_PHONE_ID, carrierId, config);
+        mCarrierConfigLoader.updateConfigForPhoneId(DEFAULT_PHONE_ID,
+                IccCardConstants.INTENT_VALUE_ICC_LOADED);
+        mTestableLooper.processAllMessages();
+
+        assertThat(mCarrierConfigLoader.getConfigFromDefaultApp(DEFAULT_PHONE_ID).getInt(
+                CARRIER_CONFIG_EXAMPLE_KEY)).isEqualTo(CARRIER_CONFIG_EXAMPLE_VALUE);
+
+    }
+
+    /**
+     * Verifies that SecurityException should throw if call #overrideConfig() without
+     * MODIFY_PHONE_STATE permission.
+     */
+    @Test
+    public void testOverrideConfig_noPermission() throws Exception {
+        assertThrows(SecurityException.class,
+                () -> mCarrierConfigLoader.overrideConfig(DEFAULT_SUB_ID, PersistableBundle.EMPTY,
+                        false));
+    }
+
+    /**
+     * Verifies that override config is not null when calling #overrideConfig with null bundle.
+     */
+    @Test
+    public void testOverrideConfig_withNullBundle() throws Exception {
+        // Bypass case if default subId is not supported by device to reduce flakiness
+        if (!SubscriptionManager.isValidPhoneId(SubscriptionManager.getPhoneId(DEFAULT_SUB_ID))) {
+            return;
+        }
+        mContext.grantPermission(STUB_PERMISSION_ENABLE_ALL);
+
+        mCarrierConfigLoader.overrideConfig(DEFAULT_SUB_ID, null /*overrides*/,
+                false/*persistent*/);
+        mTestableLooper.processAllMessages();
+
+        assertThat(mCarrierConfigLoader.getOverrideConfig(DEFAULT_PHONE_ID)).isEqualTo(
+                PersistableBundle.EMPTY);
+        verify(mSubscriptionInfoUpdater).updateSubscriptionByCarrierConfigAndNotifyComplete(
+                eq(DEFAULT_PHONE_ID), eq(PLATFORM_CARRIER_CONFIG_PACKAGE),
+                any(PersistableBundle.class), any(Message.class));
+    }
+
+    /**
+     * Verifies that override config is not null when calling #overrideConfig with non-null bundle.
+     */
+    @Test
+    public void testOverrideConfig_withNonNullBundle() throws Exception {
+        // Bypass case if default subId is not supported by device to reduce flakiness
+        if (!SubscriptionManager.isValidPhoneId(SubscriptionManager.getPhoneId(DEFAULT_SUB_ID))) {
+            return;
+        }
+        mContext.grantPermission(STUB_PERMISSION_ENABLE_ALL);
+
+        PersistableBundle config = getTestConfig();
+        mCarrierConfigLoader.overrideConfig(DEFAULT_SUB_ID, config /*overrides*/,
+                false/*persistent*/);
+        mTestableLooper.processAllMessages();
+
+        assertThat(mCarrierConfigLoader.getOverrideConfig(DEFAULT_PHONE_ID).getInt(
+                CARRIER_CONFIG_EXAMPLE_KEY)).isEqualTo(CARRIER_CONFIG_EXAMPLE_VALUE);
+        verify(mSubscriptionInfoUpdater).updateSubscriptionByCarrierConfigAndNotifyComplete(
+                eq(DEFAULT_PHONE_ID), eq(PLATFORM_CARRIER_CONFIG_PACKAGE),
+                any(PersistableBundle.class), any(Message.class));
+    }
+
+    /**
+     * Verifies that calling #notifyConfigChangedForSubId() with invalid subId will be ignored.
+     */
+    @Test
+    public void testNotifyConfigChangedForSubId_invalidSubId() throws Exception {
+        mContext.grantPermission(STUB_PERMISSION_ENABLE_ALL);
+
+        mCarrierConfigLoader.notifyConfigChangedForSubId(
+                SubscriptionManager.INVALID_SUBSCRIPTION_ID);
+
+        // verifying the behavior following the permission check is not actually performed.
+        // It against "verify value instead of behavior", but we don't have other alternatives.
+        verify(mPackageManager, never()).getNameForUid(anyInt());
+        verify(mContext, never()).checkCallingOrSelfPermission(
+                eq(android.Manifest.permission.MODIFY_PHONE_STATE));
+    }
+
+    // TODO(b/184040111): Enable test case when support disabling carrier privilege
+    // Phone/System UID always has carrier privilege (TelephonyPermission#getCarrierPrivilegeStatus)
+    // when running the test here.
+    /**
+     * Verifies that SecurityException should throw when calling notifyConfigChangedForSubId without
+     * MODIFY_PHONE_STATE permission.
+     */
+    @Ignore
+    public void testNotifyConfigChangedForSubId_noPermission() throws Exception {
+        setCarrierPrivilegesForSubId(false, DEFAULT_SUB_ID);
+
+        assertThrows(SecurityException.class,
+                () -> mCarrierConfigLoader.notifyConfigChangedForSubId(DEFAULT_SUB_ID));
+    }
+
+    /**
+     * Verifies that SecurityException should throw when calling getDefaultCarrierServicePackageName
+     * without READ_PRIVILEGED_PHONE_STATE permission.
+     */
+    @Test
+    public void testGetDefaultCarrierServicePackageName_noPermission() {
+        assertThrows(SecurityException.class,
+                () -> mCarrierConfigLoader.getDefaultCarrierServicePackageName());
+    }
+
+    /**
+     * Verifies that the right default carrier service package name is return when calling
+     * getDefaultCarrierServicePackageName with permission.
+     */
+    @Test
+    public void testGetDefaultCarrierServicePackageName_withPermission() {
+        mContext.grantPermission(STUB_PERMISSION_ENABLE_ALL);
+
+        assertThat(mCarrierConfigLoader.getDefaultCarrierServicePackageName())
+                .isEqualTo(PLATFORM_CARRIER_CONFIG_PACKAGE);
+    }
+
+    // TODO(b/184040111): Enable test case when support disabling carrier privilege
+    // Phone/System UID always has carrier privilege (TelephonyPermission#getCarrierPrivilegeStatus)
+    // when running the test here.
+    /**
+     * Verifies that without permission, #getConfigForSubId will return an empty PersistableBundle.
+     */
+    @Ignore
+    public void testGetConfigForSubId_noPermission() {
+        // Bypass case if default subId is not supported by device to reduce flakiness
+        if (!SubscriptionManager.isValidPhoneId(SubscriptionManager.getPhoneId(DEFAULT_SUB_ID))) {
+            return;
+        }
+        setCarrierPrivilegesForSubId(false, DEFAULT_SUB_ID);
+
+        assertThat(mCarrierConfigLoader.getConfigForSubId(DEFAULT_SUB_ID,
+                PLATFORM_CARRIER_CONFIG_PACKAGE)).isEqualTo(PersistableBundle.EMPTY);
+    }
+
+    /**
+     * Verifies that when have no DUMP permission, the #dump() method shows permission denial.
+     */
+    @Test
+    public void testDump_noPermission() {
+        StringWriter stringWriter = new StringWriter();
+        mCarrierConfigLoader.dump(new FileDescriptor(), new PrintWriter(stringWriter),
+                new String[0]);
+        stringWriter.flush();
+
+        assertThat(stringWriter.toString()).contains("Permission Denial:");
+    }
+
+    /**
+     * Verifies that when have DUMP permission, the #dump() method can dump the CarrierConfigLoader.
+     */
+    @Test
+    public void testDump_withPermission() {
+        mContext.grantPermission(android.Manifest.permission.DUMP);
+
+        StringWriter stringWriter = new StringWriter();
+        mCarrierConfigLoader.dump(new FileDescriptor(), new PrintWriter(stringWriter),
+                new String[0]);
+        stringWriter.flush();
+
+        String dumpContent = stringWriter.toString();
+        assertThat(dumpContent).contains("CarrierConfigLoader:");
+        assertThat(dumpContent).doesNotContain("Permission Denial:");
+    }
+
+    private static PersistableBundle getTestConfig() {
+        PersistableBundle config = new PersistableBundle();
+        config.putInt(CARRIER_CONFIG_EXAMPLE_KEY, CARRIER_CONFIG_EXAMPLE_VALUE);
+        return config;
+    }
+
+    private void setCarrierPrivilegesForSubId(boolean hasCarrierPrivileges, int subId) {
+        TelephonyManager mockTelephonyManager = Mockito.mock(TelephonyManager.class);
+        doReturn(mockTelephonyManager).when(mTelephonyManager).createForSubscriptionId(subId);
+        doReturn(hasCarrierPrivileges ? TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS
+                : TelephonyManager.CARRIER_PRIVILEGE_STATUS_NO_ACCESS).when(
+                mockTelephonyManager).getCarrierPrivilegeStatus(anyInt());
+    }
+}
