Merge "Add Private space Delete settings page inside PS settings page" into main
diff --git a/res/xml/mobile_network_settings.xml b/res/xml/mobile_network_settings.xml
index b5d0c59..a29e123 100644
--- a/res/xml/mobile_network_settings.xml
+++ b/res/xml/mobile_network_settings.xml
@@ -48,6 +48,23 @@
             settings:controller="com.android.settings.network.telephony.SmsDefaultSubscriptionController"/>
 
         <Preference
+            android:key="mobile_network_spn"
+            android:title="@string/mobile_network_spn_title"
+            android:summary="@string/summary_placeholder"
+            android:selectable="false"
+            settings:controller="com.android.settings.network.telephony.MobileNetworkSpnPreferenceController"
+            settings:allowDividerAbove="true" />
+
+        <Preference
+            android:key="phone_number"
+            android:title="@string/status_number"
+            android:summary="@string/summary_placeholder"
+            android:selectable="false"
+            settings:controller="com.android.settings.network.telephony.MobileNetworkPhoneNumberPreferenceController"
+            settings:allowDividerBelow="true"
+            settings:enableCopying="true"/>
+
+        <Preference
             android:key="cdma_lte_data_service_key"
             android:title="@string/cdma_lte_data_service"
             settings:controller="com.android.settings.network.telephony.DataServiceSetupPreferenceController"
@@ -162,6 +179,24 @@
             settings:controller="com.android.settings.network.telephony.CarrierSettingsVersionPreferenceController"
             settings:enableCopying="true"/>
 
+        <!-- IMEI -->
+        <Preference
+            android:key="network_mode_imei_info"
+            android:title="@string/status_imei"
+            android:summary="@string/summary_placeholder"
+            settings:keywords="@string/keywords_imei_info"
+            settings:enableCopying="true"
+            settings:controller="com.android.settings.network.telephony.MobileNetworkImeiPreferenceController"/>
+        <!-- EID -->
+        <com.android.settingslib.CustomDialogPreferenceCompat
+            android:key="network_mode_eid_info"
+            android:title="@string/status_eid"
+            android:summary="@string/device_info_protected_single_press"
+            android:positiveButtonText="@string/dlg_ok"
+            android:dialogLayout="@layout/dialog_eid_status"
+            settings:enableCopying="true"
+            settings:controller="com.android.settings.network.telephony.MobileNetworkEidPreferenceController"/>
+
         <PreferenceCategory
             android:key="calling_category"
             android:title="@string/call_category"
diff --git a/res/xml/my_device_info.xml b/res/xml/my_device_info.xml
index 29c3c62..62bc040 100644
--- a/res/xml/my_device_info.xml
+++ b/res/xml/my_device_info.xml
@@ -52,11 +52,12 @@
             settings:controller="com.android.settings.deviceinfo.BrandedAccountPreferenceController"/>
 
         <!-- Phone number -->
-        <com.android.settings.deviceinfo.PhoneNumberSummaryPreference
+        <Preference
             android:key="phone_number"
             android:order="3"
             android:title="@string/status_number"
             android:summary="@string/summary_placeholder"
+            android:selectable="false"
             settings:isPreferenceVisible="@bool/config_show_sim_info"
             settings:controller="com.android.settings.deviceinfo.PhoneNumberPreferenceController"
             settings:enableCopying="true"/>
@@ -118,7 +119,6 @@
             android:key="eid_info"
             android:order="31"
             android:title="@string/status_eid"
-            android:summary="@string/device_info_protected_single_press"
             android:positiveButtonText="@string/dlg_ok"
             android:dialogLayout="@layout/dialog_eid_status"
             settings:isPreferenceVisible="@bool/config_show_sim_info"
@@ -126,7 +126,7 @@
             settings:controller="com.android.settings.deviceinfo.simstatus.SimEidPreferenceController"/>
 
         <!-- IMEI -->
-        <com.android.settings.deviceinfo.PhoneNumberSummaryPreference
+        <Preference
             android:key="imei_info"
             android:order="32"
             android:title="@string/status_imei"
diff --git a/src/com/android/settings/deviceinfo/PhoneNumberPreferenceController.java b/src/com/android/settings/deviceinfo/PhoneNumberPreferenceController.java
index d1bf808..8e583fd 100644
--- a/src/com/android/settings/deviceinfo/PhoneNumberPreferenceController.java
+++ b/src/com/android/settings/deviceinfo/PhoneNumberPreferenceController.java
@@ -56,28 +56,6 @@
     }
 
     @Override
-    public CharSequence getSummary() {
-        return mContext.getString(R.string.device_info_protected_single_press);
-    }
-
-    @Override
-    public boolean handlePreferenceTreeClick(Preference preference) {
-        String prefKey = preference.getKey();
-        if (prefKey.startsWith(KEY_PHONE_NUMBER)) {
-            int simSlotNumber = 0;
-            if (!TextUtils.equals(prefKey, KEY_PHONE_NUMBER)) {
-                // Get multisim slot number from preference key.
-                // Multisim preference key is KEY_PHONE_NUMBER + simSlotNumber
-                simSlotNumber = Integer.parseInt(
-                        prefKey.replaceAll("[^0-9]", ""));
-            }
-            final Preference simStatusPreference = mPreferenceList.get(simSlotNumber);
-            simStatusPreference.setSummary(getPhoneNumber(simSlotNumber));
-        }
-        return super.handlePreferenceTreeClick(preference);
-    }
-
-    @Override
     public void displayPreference(PreferenceScreen screen) {
         super.displayPreference(screen);
         if (!SubscriptionUtil.isSimHardwareVisible(mContext)) {
@@ -105,7 +83,7 @@
         for (int simSlotNumber = 0; simSlotNumber < mPreferenceList.size(); simSlotNumber++) {
             final Preference simStatusPreference = mPreferenceList.get(simSlotNumber);
             simStatusPreference.setTitle(getPreferenceTitle(simSlotNumber));
-            simStatusPreference.setSummary(getSummary());
+            simStatusPreference.setSummary(getPhoneNumber(simSlotNumber));
         }
     }
 
@@ -155,7 +133,7 @@
     }
 
     @VisibleForTesting
-    protected CharSequence getFormattedPhoneNumber(SubscriptionInfo subscriptionInfo) {
+    protected String getFormattedPhoneNumber(SubscriptionInfo subscriptionInfo) {
         final String phoneNumber = SubscriptionUtil.getBidiFormattedPhoneNumber(mContext,
                 subscriptionInfo);
         return TextUtils.isEmpty(phoneNumber) ? mContext.getString(R.string.device_info_default)
@@ -164,6 +142,6 @@
 
     @VisibleForTesting
     protected Preference createNewPreference(Context context) {
-        return new PhoneNumberSummaryPreference(context);
+        return new Preference(context);
     }
 }
diff --git a/src/com/android/settings/deviceinfo/imei/ImeiInfoPreferenceController.java b/src/com/android/settings/deviceinfo/imei/ImeiInfoPreferenceController.java
index 2045b96..ff55184 100644
--- a/src/com/android/settings/deviceinfo/imei/ImeiInfoPreferenceController.java
+++ b/src/com/android/settings/deviceinfo/imei/ImeiInfoPreferenceController.java
@@ -33,7 +33,6 @@
 
 import com.android.settings.R;
 import com.android.settings.core.BasePreferenceController;
-import com.android.settings.deviceinfo.PhoneNumberSummaryPreference;
 import com.android.settings.deviceinfo.simstatus.SlotSimStatus;
 import com.android.settings.network.SubscriptionUtil;
 import com.android.settingslib.Utils;
@@ -103,6 +102,7 @@
             multiImeiPreference.setKey(DEFAULT_KEY + (1 + simSlotNumber));
             multiImeiPreference.setEnabled(true);
             multiImeiPreference.setCopyingEnabled(true);
+
             category.addPreference(multiImeiPreference);
        }
     }
@@ -112,11 +112,6 @@
         updatePreference(preference, keyToSlotIndex(preference.getKey()));
     }
 
-    @Override
-    public CharSequence getSummary() {
-        return mContext.getString(R.string.device_info_protected_single_press);
-    }
-
     private CharSequence getSummary(int simSlot) {
         final int phoneType = getPhoneType(simSlot);
         return phoneType == PHONE_TYPE_CDMA ? mTelephonyManager.getMeid(simSlot)
@@ -150,8 +145,12 @@
 
     @VisibleForTesting
     protected void updatePreference(Preference preference, int simSlot) {
+        if (simSlot < 0) {
+            preference.setVisible(false);
+            return;
+        }
         preference.setTitle(getTitle(simSlot));
-        preference.setSummary(getSummary());
+        preference.setSummary(getSummary(simSlot));
     }
 
     private CharSequence getTitleForGsmPhone(int simSlot, boolean isPrimaryImei) {
@@ -195,6 +194,6 @@
 
     @VisibleForTesting
     Preference createNewPreference(Context context) {
-        return new PhoneNumberSummaryPreference(context);
+        return new Preference(context);
     }
 }
diff --git a/src/com/android/settings/deviceinfo/simstatus/SimEidPreferenceController.kt b/src/com/android/settings/deviceinfo/simstatus/SimEidPreferenceController.kt
index e0376dc..f765d8c 100644
--- a/src/com/android/settings/deviceinfo/simstatus/SimEidPreferenceController.kt
+++ b/src/com/android/settings/deviceinfo/simstatus/SimEidPreferenceController.kt
@@ -92,6 +92,7 @@
             }
             preference.title = title
             preference.dialogTitle = title
+            preference.summary = eid
             updateDialog()
         }
     }
@@ -130,9 +131,6 @@
 
         val qrCodeView = dialog.requireViewById<ImageView>(R.id.esim_id_qrcode)
         qrCodeView.setImageBitmap(getEidQrCode(eid))
-
-        // After "Tap to show", eid is displayed on preference.
-        preference.summary = textView.text
     }
 
     override fun handlePreferenceTreeClick(preference: Preference): Boolean {
diff --git a/src/com/android/settings/network/telephony/AutoDataSwitchPreferenceController.java b/src/com/android/settings/network/telephony/AutoDataSwitchPreferenceController.java
index 378d9a1..ef74a2e 100644
--- a/src/com/android/settings/network/telephony/AutoDataSwitchPreferenceController.java
+++ b/src/com/android/settings/network/telephony/AutoDataSwitchPreferenceController.java
@@ -42,6 +42,7 @@
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.settings.R;
 import com.android.settings.datausage.DataUsageUtils;
+import com.android.settings.flags.Flags;
 import com.android.settings.network.MobileDataContentObserver;
 import com.android.settings.network.ProxySubscriptionManager;
 import com.android.settings.network.SubscriptionsChangeListener;
@@ -194,7 +195,8 @@
 
     @Override
     public int getAvailabilityStatus(int subId) {
-        if (!SubscriptionManager.isValidSubscriptionId(subId)
+        if (Flags.isDualSimOnboardingEnabled()
+                || !SubscriptionManager.isValidSubscriptionId(subId)
                 || SubscriptionManager.getDefaultDataSubscriptionId() == subId
                 || (!hasMobileData())) {
             return CONDITIONALLY_UNAVAILABLE;
diff --git a/src/com/android/settings/network/telephony/DefaultSubscriptionController.java b/src/com/android/settings/network/telephony/DefaultSubscriptionController.java
index 206b3a9..03ce7f6 100644
--- a/src/com/android/settings/network/telephony/DefaultSubscriptionController.java
+++ b/src/com/android/settings/network/telephony/DefaultSubscriptionController.java
@@ -32,6 +32,7 @@
 
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.settings.R;
+import com.android.settings.flags.Flags;
 import com.android.settings.network.DefaultSubscriptionReceiver;
 import com.android.settings.network.MobileNetworkRepository;
 import com.android.settingslib.core.lifecycle.Lifecycle;
@@ -88,6 +89,9 @@
 
     @Override
     public int getAvailabilityStatus(int subId) {
+        if (Flags.isDualSimOnboardingEnabled()) {
+            return CONDITIONALLY_UNAVAILABLE;
+        }
         return AVAILABLE;
     }
 
diff --git a/src/com/android/settings/network/telephony/MobileDataPreferenceController.java b/src/com/android/settings/network/telephony/MobileDataPreferenceController.java
index 06015d4..bec7ee7 100644
--- a/src/com/android/settings/network/telephony/MobileDataPreferenceController.java
+++ b/src/com/android/settings/network/telephony/MobileDataPreferenceController.java
@@ -34,6 +34,7 @@
 import androidx.preference.TwoStatePreference;
 
 import com.android.settings.R;
+import com.android.settings.flags.Flags;
 import com.android.settings.network.MobileNetworkRepository;
 import com.android.settings.wifi.WifiPickerTrackerHelper;
 import com.android.settingslib.core.lifecycle.Lifecycle;
@@ -83,6 +84,9 @@
 
     @Override
     public int getAvailabilityStatus(int subId) {
+        if (Flags.isDualSimOnboardingEnabled()) {
+            return CONDITIONALLY_UNAVAILABLE;
+        }
         return subId != SubscriptionManager.INVALID_SUBSCRIPTION_ID
                 ? AVAILABLE
                 : AVAILABLE_UNSEARCHABLE;
diff --git a/src/com/android/settings/network/telephony/MobileNetworkEidPreferenceController.kt b/src/com/android/settings/network/telephony/MobileNetworkEidPreferenceController.kt
new file mode 100644
index 0000000..907bab1
--- /dev/null
+++ b/src/com/android/settings/network/telephony/MobileNetworkEidPreferenceController.kt
@@ -0,0 +1,220 @@
+/*
+ * Copyright (C) 2024 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.settings.network.telephony
+
+import android.content.Context
+import android.graphics.Bitmap
+import android.telephony.SubscriptionInfo
+import android.telephony.SubscriptionManager
+import android.telephony.TelephonyManager
+import android.telephony.euicc.EuiccManager
+import android.text.TextUtils
+import android.util.Log
+import android.view.WindowManager
+import android.widget.ImageView
+import android.widget.TextView
+import androidx.annotation.VisibleForTesting
+import androidx.fragment.app.Fragment
+import androidx.fragment.app.viewModels
+import androidx.lifecycle.LifecycleOwner
+import androidx.lifecycle.lifecycleScope
+import androidx.preference.Preference
+import androidx.preference.PreferenceScreen
+import com.android.settings.R
+import com.android.settings.deviceinfo.PhoneNumberUtil
+import com.android.settings.flags.Flags
+import com.android.settings.network.SubscriptionInfoListViewModel
+import com.android.settings.network.SubscriptionUtil
+import com.android.settingslib.CustomDialogPreferenceCompat
+import com.android.settingslib.Utils
+import com.android.settingslib.qrcode.QrCodeGenerator
+import com.android.settingslib.spa.framework.util.collectLatestWithLifecycle
+import com.android.settingslib.spaprivileged.framework.common.userManager
+import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.Dispatchers
+import kotlinx.coroutines.flow.map
+import kotlinx.coroutines.launch
+import kotlinx.coroutines.withContext
+
+/**
+ * Preference controller for "EID"
+ */
+open class MobileNetworkEidPreferenceController(context: Context, key: String) :
+    TelephonyBasePreferenceController(context, key) {
+
+    private lateinit var lazyViewModel: Lazy<SubscriptionInfoListViewModel>
+    private lateinit var preference: CustomDialogPreferenceCompat
+    private lateinit var fragment: Fragment
+    private var coroutineScope: CoroutineScope? = null
+    private var title = String()
+    private var eid = String()
+
+    fun init(fragment: Fragment, subId: Int) {
+        this.fragment = fragment
+        lazyViewModel = fragment.viewModels()
+        mSubId = subId
+    }
+
+    override fun getAvailabilityStatus(subId: Int): Int = when {
+        !Flags.isDualSimOnboardingEnabled() -> CONDITIONALLY_UNAVAILABLE
+        SubscriptionManager.isValidSubscriptionId(subId)
+                && eid.isNotEmpty()
+                && mContext.userManager.isAdminUser -> AVAILABLE
+
+        else -> CONDITIONALLY_UNAVAILABLE
+    }
+
+    override fun displayPreference(screen: PreferenceScreen) {
+        super.displayPreference(screen)
+        preference = screen.findPreference(preferenceKey)!!
+    }
+
+    override fun onViewCreated(viewLifecycleOwner: LifecycleOwner) {
+        preference.isVisible = false
+
+        val viewModel by lazyViewModel
+        coroutineScope = viewLifecycleOwner.lifecycleScope
+        viewModel.subscriptionInfoListFlow
+            .map { subscriptionInfoList ->
+                subscriptionInfoList
+                    .firstOrNull { subInfo ->
+                        subInfo.subscriptionId == mSubId && subInfo.isEmbedded
+                    }
+            }
+            .collectLatestWithLifecycle(viewLifecycleOwner) { subscriptionInfo ->
+                subscriptionInfo?.let {
+                    coroutineScope?.launch {
+                        refreshData(it)
+                    }
+                }
+            }
+    }
+
+    @VisibleForTesting
+    suspend fun refreshData(subscriptionInfo: SubscriptionInfo) {
+        withContext(Dispatchers.Default) {
+            eid = getEid(subscriptionInfo)
+            if (eid.isEmpty()) {
+                Log.d(TAG, "EID is empty.")
+            }
+            title = getTitle()
+        }
+        refreshUi()
+    }
+
+    fun refreshUi() {
+        preference.title = title
+        preference.dialogTitle = title
+        preference.summary = eid
+        preference.isVisible = eid.isNotEmpty()
+    }
+
+    override fun handlePreferenceTreeClick(preference: Preference): Boolean {
+        if (preference.key != preferenceKey) return false
+        this.preference.setOnShowListener {
+            coroutineScope?.launch { updateDialog() }
+        }
+        return true
+    }
+
+    private fun getTitle(): String {
+        return mContext.getString(R.string.status_eid)
+    }
+
+    private suspend fun updateDialog() {
+        val dialog = preference.dialog ?: return
+        dialog.window?.setFlags(
+            WindowManager.LayoutParams.FLAG_SECURE,
+            WindowManager.LayoutParams.FLAG_SECURE
+        )
+        dialog.setCanceledOnTouchOutside(false)
+        val textView = dialog.requireViewById<TextView>(R.id.esim_id_value)
+        textView.text = PhoneNumberUtil.expandByTts(eid)
+
+        val qrCodeView = dialog.requireViewById<ImageView>(R.id.esim_id_qrcode)
+
+        qrCodeView.setImageBitmap(getEidQrCode(eid))
+    }
+
+    protected fun getTelephonyManager(context: Context): TelephonyManager? {
+        return context.getSystemService(TelephonyManager::class.java)
+    }
+
+    protected fun getEuiccManager(context: Context): EuiccManager? {
+        return context.getSystemService(EuiccManager::class.java)
+    }
+
+    @VisibleForTesting
+    fun getEid(subscriptionInfo: SubscriptionInfo): String {
+        val euiccMgr = getEuiccManager(mContext)
+        val telMgr = getTelephonyManager(mContext)
+        if(euiccMgr==null || telMgr==null) return String()
+
+        var eid = getEidPerSlot(telMgr, euiccMgr, subscriptionInfo)
+        return eid.ifEmpty {
+            getDefaultEid(euiccMgr)
+        }
+    }
+
+    private fun getEidPerSlot(
+        telMgr: TelephonyManager,
+        euiccMgr: EuiccManager,
+        subscriptionInfo: SubscriptionInfo
+    ): String {
+        val uiccCardInfoList = telMgr.uiccCardsInfo
+        val cardId = subscriptionInfo.cardId
+
+        /**
+         * Find EID from first slot which contains an eSIM and with card ID within
+         * the eSIM card ID provided by SubscriptionManager.
+         */
+        return uiccCardInfoList.firstOrNull { cardInfo -> cardInfo.isEuicc && cardInfo.cardId == cardId }
+            ?.let { cardInfo ->
+                var eid = cardInfo.getEid()
+                if (TextUtils.isEmpty(eid)) {
+                    eid = euiccMgr.createForCardId(cardInfo.cardId).getEid()
+                }
+                eid
+            } ?: String()
+    }
+
+    private fun getDefaultEid(euiccMgr: EuiccManager?): String {
+        return if (euiccMgr == null || !euiccMgr.isEnabled) {
+            String()
+        } else euiccMgr.getEid() ?: String()
+    }
+
+    companion object {
+        private const val TAG = "MobileNetworkEidPreferenceController"
+        private const val QR_CODE_SIZE = 600
+
+        /**
+         * Gets the QR code for EID
+         * @param eid is the EID string
+         * @return a Bitmap of QR code
+         */
+        private suspend fun getEidQrCode(eid: String): Bitmap? = withContext(Dispatchers.Default) {
+            try {
+                Log.d(TAG, "updateDialog. getEidQrCode $eid")
+                QrCodeGenerator.encodeQrCode(contents = eid, size = QR_CODE_SIZE)
+            } catch (exception: Exception) {
+                Log.w(TAG, "Error when creating QR code width $QR_CODE_SIZE", exception)
+                null
+            }
+        }
+    }
+}
diff --git a/src/com/android/settings/network/telephony/MobileNetworkImeiPreferenceController.kt b/src/com/android/settings/network/telephony/MobileNetworkImeiPreferenceController.kt
new file mode 100644
index 0000000..8ec313b
--- /dev/null
+++ b/src/com/android/settings/network/telephony/MobileNetworkImeiPreferenceController.kt
@@ -0,0 +1,145 @@
+/*
+ * Copyright (C) 2024 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.settings.network.telephony
+
+import android.content.Context
+import android.os.UserManager
+import android.telephony.SubscriptionInfo
+import android.telephony.SubscriptionManager
+import android.telephony.TelephonyManager
+import android.util.Log
+import androidx.annotation.VisibleForTesting
+import androidx.fragment.app.Fragment
+import androidx.fragment.app.viewModels
+import androidx.lifecycle.LifecycleOwner
+import androidx.lifecycle.lifecycleScope
+import androidx.preference.Preference
+import androidx.preference.PreferenceScreen
+import com.android.settings.R
+import com.android.settings.deviceinfo.imei.ImeiInfoDialogFragment
+import com.android.settings.flags.Flags
+import com.android.settings.network.SubscriptionInfoListViewModel
+import com.android.settings.network.SubscriptionUtil
+import com.android.settingslib.Utils
+import com.android.settingslib.spa.framework.util.collectLatestWithLifecycle
+import com.android.settingslib.spaprivileged.framework.common.userManager
+import kotlinx.coroutines.Dispatchers
+import kotlinx.coroutines.launch
+import kotlinx.coroutines.withContext
+
+/**
+ * Preference controller for "IMEI"
+ */
+class MobileNetworkImeiPreferenceController(context: Context, key: String) :
+    TelephonyBasePreferenceController(context, key) {
+
+    private lateinit var lazyViewModel: Lazy<SubscriptionInfoListViewModel>
+    private lateinit var preference: Preference
+    private lateinit var fragment: Fragment
+    private lateinit var mTelephonyManager: TelephonyManager
+    private var simSlot = -1
+    private var imei = String()
+    private var title = String()
+
+    fun init(fragment: Fragment, subId: Int) {
+        this.fragment = fragment
+        lazyViewModel = fragment.viewModels()
+        mSubId = subId
+        mTelephonyManager = mContext.getSystemService(TelephonyManager::class.java)
+            ?.createForSubscriptionId(mSubId)!!
+    }
+
+    override fun getAvailabilityStatus(subId: Int): Int = when {
+        !Flags.isDualSimOnboardingEnabled() -> CONDITIONALLY_UNAVAILABLE
+        SubscriptionManager.isValidSubscriptionId(subId)
+                && SubscriptionUtil.isSimHardwareVisible(mContext)
+                && mContext.userManager.isAdminUser
+                && !Utils.isWifiOnly(mContext) -> AVAILABLE
+        else -> CONDITIONALLY_UNAVAILABLE
+    }
+
+    override fun displayPreference(screen: PreferenceScreen) {
+        super.displayPreference(screen)
+        preference = screen.findPreference(preferenceKey)!!
+    }
+
+    override fun onViewCreated(viewLifecycleOwner: LifecycleOwner) {
+        val viewModel by lazyViewModel
+        val coroutineScope = viewLifecycleOwner.lifecycleScope
+
+        viewModel.subscriptionInfoListFlow
+                .collectLatestWithLifecycle(viewLifecycleOwner) { subscriptionInfoList ->
+                    subscriptionInfoList
+                            .firstOrNull { subInfo -> subInfo.subscriptionId == mSubId }
+                            ?.let {
+                                coroutineScope.launch {
+                                    refreshData(it)
+                                }
+                            }
+                }
+    }
+
+    @VisibleForTesting
+    suspend fun refreshData(subscription:SubscriptionInfo){
+        withContext(Dispatchers.Default) {
+            title = getTitle()
+            imei = getImei()
+            simSlot = subscription.simSlotIndex
+        }
+        refreshUi()
+    }
+
+    private fun refreshUi(){
+        preference.title = title
+        preference.summary = imei
+        preference.isVisible = true
+    }
+
+    override fun handlePreferenceTreeClick(preference: Preference): Boolean {
+        if (preference.key != preferenceKey) return false
+
+        Log.d(TAG, "handlePreferenceTreeClick:")
+        ImeiInfoDialogFragment.show(fragment, simSlot, preference.title.toString())
+        return true
+    }
+    private fun getImei(): String {
+        val phoneType = getPhoneType()
+        return if (phoneType == TelephonyManager.PHONE_TYPE_CDMA) mTelephonyManager.meid?: String()
+                else mTelephonyManager.imei?: String()
+    }
+    private fun getTitleForGsmPhone(): String {
+        return mContext.getString(R.string.status_imei)
+    }
+
+    private fun getTitleForCdmaPhone(): String {
+        return mContext.getString(R.string.status_meid_number)
+    }
+
+    private fun getTitle(): String {
+        val phoneType = getPhoneType()
+        return if (phoneType == TelephonyManager.PHONE_TYPE_CDMA) getTitleForCdmaPhone()
+                else getTitleForGsmPhone()
+    }
+
+    fun getPhoneType(): Int {
+        return mTelephonyManager.currentPhoneType
+    }
+
+    companion object {
+        private const val TAG = "MobileNetworkImeiPreferenceController"
+    }
+}
diff --git a/src/com/android/settings/network/telephony/MobileNetworkPhoneNumberPreferenceController.kt b/src/com/android/settings/network/telephony/MobileNetworkPhoneNumberPreferenceController.kt
new file mode 100644
index 0000000..65a4b7e
--- /dev/null
+++ b/src/com/android/settings/network/telephony/MobileNetworkPhoneNumberPreferenceController.kt
@@ -0,0 +1,112 @@
+/*
+ * Copyright (C) 2024 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.settings.network.telephony
+
+import android.content.Context
+import android.telephony.SubscriptionInfo
+import android.telephony.SubscriptionManager
+import androidx.annotation.VisibleForTesting
+import androidx.fragment.app.Fragment
+import androidx.fragment.app.viewModels
+import androidx.lifecycle.LifecycleOwner
+import androidx.lifecycle.lifecycleScope
+import androidx.preference.Preference
+import androidx.preference.PreferenceScreen
+import com.android.settings.R
+import com.android.settings.flags.Flags
+import com.android.settings.network.SubscriptionInfoListViewModel
+import com.android.settings.network.SubscriptionUtil
+import com.android.settingslib.spa.framework.util.collectLatestWithLifecycle
+import kotlinx.coroutines.Dispatchers
+import kotlinx.coroutines.flow.flowOn
+import kotlinx.coroutines.flow.map
+import kotlinx.coroutines.launch
+import kotlinx.coroutines.withContext
+
+/**
+ * Preference controller for "Phone number"
+ */
+class MobileNetworkPhoneNumberPreferenceController(context: Context, key: String) :
+    TelephonyBasePreferenceController(context, key) {
+
+    private lateinit var lazyViewModel: Lazy<SubscriptionInfoListViewModel>
+    private lateinit var preference: Preference
+
+    private var phoneNumber = String()
+
+    fun init(fragment: Fragment, subId: Int) {
+        lazyViewModel = fragment.viewModels()
+        mSubId = subId
+    }
+
+    override fun getAvailabilityStatus(subId: Int): Int = when {
+        !Flags.isDualSimOnboardingEnabled() -> CONDITIONALLY_UNAVAILABLE
+        SubscriptionManager.isValidSubscriptionId(subId)
+                && SubscriptionUtil.isSimHardwareVisible(mContext) -> AVAILABLE
+        else -> CONDITIONALLY_UNAVAILABLE
+    }
+
+    override fun displayPreference(screen: PreferenceScreen) {
+        super.displayPreference(screen)
+        preference = screen.findPreference(preferenceKey)!!
+    }
+
+    override fun onViewCreated(viewLifecycleOwner: LifecycleOwner) {
+        val viewModel by lazyViewModel
+        val coroutineScope = viewLifecycleOwner.lifecycleScope
+
+        viewModel.subscriptionInfoListFlow
+            .map { subscriptionInfoList ->
+                subscriptionInfoList
+                    .firstOrNull { subInfo -> subInfo.subscriptionId == mSubId }
+            }
+            .flowOn(Dispatchers.Default)
+            .collectLatestWithLifecycle(viewLifecycleOwner) {
+                it?.let {
+                    coroutineScope.launch {
+                        refreshData(it)
+                    }
+                }
+            }
+    }
+
+    @VisibleForTesting
+    suspend fun refreshData(subscriptionInfo: SubscriptionInfo){
+        withContext(Dispatchers.Default) {
+            phoneNumber = getFormattedPhoneNumber(subscriptionInfo)
+        }
+        refreshUi()
+    }
+
+    private fun refreshUi(){
+        preference.summary = phoneNumber
+    }
+
+    private fun getFormattedPhoneNumber(subscriptionInfo: SubscriptionInfo?): String {
+        val phoneNumber = SubscriptionUtil.getBidiFormattedPhoneNumber(
+            mContext,
+            subscriptionInfo
+        )
+        return phoneNumber
+            ?.let { return it.ifEmpty { getStringUnknown() } }
+            ?: getStringUnknown()
+    }
+
+    private fun getStringUnknown(): String {
+        return mContext.getString(R.string.device_info_default)
+    }
+}
diff --git a/src/com/android/settings/network/telephony/MobileNetworkSettings.java b/src/com/android/settings/network/telephony/MobileNetworkSettings.java
index 4188f8d..2f2b20e 100644
--- a/src/com/android/settings/network/telephony/MobileNetworkSettings.java
+++ b/src/com/android/settings/network/telephony/MobileNetworkSettings.java
@@ -85,6 +85,7 @@
     private static final String KEY_SMS_PREF = "sms_preference";
     private static final String KEY_MOBILE_DATA_PREF = "mobile_data_enable";
     private static final String KEY_CONVERT_TO_ESIM_PREF = "convert_to_esim";
+    private static final String KEY_EID_KEY = "network_mode_eid_info";
 
     //String keys for preference lookup
     private static final String BUTTON_CDMA_SYSTEM_SELECT_KEY = "cdma_system_select_key";
@@ -171,6 +172,10 @@
                             String.valueOf(mSubId));
         });
 
+        MobileNetworkEidPreferenceController eid = new MobileNetworkEidPreferenceController(context,
+                KEY_EID_KEY);
+        eid.init(this, mSubId);
+
         return Arrays.asList(
                 new DataUsageSummaryPreferenceController(context, mSubId),
                 new RoamingPreferenceController(context, KEY_ROAMING_PREF, getSettingsLifecycle(),
@@ -182,7 +187,7 @@
                 new MobileDataPreferenceController(context, KEY_MOBILE_DATA_PREF,
                         getSettingsLifecycle(), this, mSubId),
                 new ConvertToEsimPreferenceController(context, KEY_CONVERT_TO_ESIM_PREF,
-                        getSettingsLifecycle(), this, mSubId));
+                        getSettingsLifecycle(), this, mSubId), eid);
     }
 
     @Override
@@ -239,6 +244,10 @@
         use(DisableSimFooterPreferenceController.class).init(mSubId);
         use(NrDisabledInDsdsFooterPreferenceController.class).init(mSubId);
 
+        use(MobileNetworkSpnPreferenceController.class).init(this, mSubId);
+        use(MobileNetworkPhoneNumberPreferenceController.class).init(this, mSubId);
+        use(MobileNetworkImeiPreferenceController.class).init(this, mSubId);
+
         final MobileDataPreferenceController mobileDataPreferenceController =
                 use(MobileDataPreferenceController.class);
         if (mobileDataPreferenceController != null) {
diff --git a/src/com/android/settings/network/telephony/MobileNetworkSpnPreferenceController.kt b/src/com/android/settings/network/telephony/MobileNetworkSpnPreferenceController.kt
new file mode 100644
index 0000000..ac055b0
--- /dev/null
+++ b/src/com/android/settings/network/telephony/MobileNetworkSpnPreferenceController.kt
@@ -0,0 +1,81 @@
+/*
+ * Copyright (C) 2024 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.settings.network.telephony
+
+import android.content.Context
+import android.telephony.SubscriptionInfo
+import android.telephony.SubscriptionManager
+import androidx.annotation.VisibleForTesting
+import androidx.fragment.app.Fragment
+import androidx.fragment.app.viewModels
+import androidx.lifecycle.LifecycleOwner
+import androidx.preference.Preference
+import androidx.preference.PreferenceScreen
+import com.android.settings.flags.Flags
+import com.android.settings.network.SubscriptionInfoListViewModel
+import com.android.settingslib.spa.framework.util.collectLatestWithLifecycle
+
+/**
+ * Preference controller for "Mobile network" and showing the SPN.
+ */
+class MobileNetworkSpnPreferenceController(context: Context, key: String) :
+    TelephonyBasePreferenceController(context, key) {
+
+    private lateinit var lazyViewModel: Lazy<SubscriptionInfoListViewModel>
+    private lateinit var preference: Preference
+
+    private var spn = String()
+
+    fun init(fragment: Fragment, subId: Int) {
+        lazyViewModel = fragment.viewModels()
+        mSubId = subId
+    }
+
+    override fun getAvailabilityStatus(subId: Int): Int = when {
+        !Flags.isDualSimOnboardingEnabled() -> CONDITIONALLY_UNAVAILABLE
+        SubscriptionManager.isValidSubscriptionId(subId)-> AVAILABLE
+        else -> CONDITIONALLY_UNAVAILABLE
+    }
+
+    override fun displayPreference(screen: PreferenceScreen) {
+        super.displayPreference(screen)
+        preference = screen.findPreference(preferenceKey)!!
+    }
+
+    override fun onViewCreated(viewLifecycleOwner: LifecycleOwner) {
+        val viewModel by lazyViewModel
+
+        viewModel.subscriptionInfoListFlow
+                .collectLatestWithLifecycle(viewLifecycleOwner) { subscriptionInfoList ->
+                    refreshData(subscriptionInfoList)
+                }
+    }
+
+    @VisibleForTesting
+    fun refreshData(subscriptionInfoList: List<SubscriptionInfo>){
+        spn = subscriptionInfoList
+            .firstOrNull { subInfo -> subInfo.subscriptionId == mSubId }
+            ?.let { info -> info.carrierName.toString() }
+            ?: String()
+
+        refreshUi()
+    }
+
+    private fun refreshUi(){
+        preference.summary = spn
+    }
+}
diff --git a/tests/spa_unit/src/com/android/settings/network/telephony/MobileNetworkEidPreferenceControllerTest.kt b/tests/spa_unit/src/com/android/settings/network/telephony/MobileNetworkEidPreferenceControllerTest.kt
new file mode 100644
index 0000000..b035af5
--- /dev/null
+++ b/tests/spa_unit/src/com/android/settings/network/telephony/MobileNetworkEidPreferenceControllerTest.kt
@@ -0,0 +1,160 @@
+/*
+ * Copyright (C) 2024 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.settings.network.telephony
+
+import android.content.Context
+import android.platform.test.flag.junit.SetFlagsRule
+import android.telephony.SubscriptionInfo
+import android.telephony.TelephonyManager
+import android.telephony.euicc.EuiccManager
+import androidx.fragment.app.Fragment
+import androidx.preference.PreferenceManager
+import androidx.test.core.app.ApplicationProvider
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import com.android.dx.mockito.inline.extended.ExtendedMockito
+import com.android.settings.core.BasePreferenceController
+import com.android.settings.flags.Flags
+import com.android.settings.network.SubscriptionInfoListViewModel
+import com.android.settings.network.SubscriptionUtil
+import com.android.settingslib.CustomDialogPreferenceCompat
+import com.google.common.truth.Truth.assertThat
+import kotlinx.coroutines.runBlocking
+import org.junit.After
+import org.junit.Before
+import org.junit.Rule
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.mockito.MockitoSession
+import org.mockito.kotlin.any
+import org.mockito.kotlin.doReturn
+import org.mockito.kotlin.mock
+import org.mockito.kotlin.spy
+import org.mockito.kotlin.stub
+import org.mockito.kotlin.whenever
+import org.mockito.quality.Strictness
+
+@RunWith(AndroidJUnit4::class)
+class MobileNetworkEidPreferenceControllerTest {
+    @get:Rule val setFlagsRule: SetFlagsRule = SetFlagsRule()
+
+    private lateinit var mockSession: MockitoSession
+
+    private val mockViewModels =  mock<Lazy<SubscriptionInfoListViewModel>>()
+    private val mockFragment = mock<Fragment>{
+        val viewmodel = mockViewModels
+    }
+
+    private var mockEid = String()
+    private val mockTelephonyManager = mock<TelephonyManager> {
+        on {uiccCardsInfo} doReturn listOf()
+        on { createForSubscriptionId(any()) } doReturn mock
+    }
+    private val mockEuiccManager = mock<EuiccManager> {
+        on {isEnabled} doReturn true
+        on {eid} doReturn mockEid
+    }
+    private val context: Context = spy(ApplicationProvider.getApplicationContext()) {
+        on { getSystemService(TelephonyManager::class.java) } doReturn mockTelephonyManager
+        on { getSystemService(EuiccManager::class.java) } doReturn mockEuiccManager
+    }
+
+    private val controller = MobileNetworkEidPreferenceController(context, TEST_KEY)
+    private val preference = CustomDialogPreferenceCompat(context).apply { key = TEST_KEY }
+    private val preferenceScreen = PreferenceManager(context).createPreferenceScreen(context)
+
+    @Before
+    fun setUp() {
+        mockSession = ExtendedMockito.mockitoSession()
+            .initMocks(this)
+            .mockStatic(SubscriptionUtil::class.java)
+            .strictness(Strictness.LENIENT)
+            .startMocking()
+
+        preferenceScreen.addPreference(preference)
+        controller.displayPreference(preferenceScreen)
+    }
+
+    @After
+    fun tearDown() {
+        mockSession.finishMocking()
+    }
+
+    @Test
+    fun refreshData_getEmptyEid_preferenceIsNotVisible() = runBlocking {
+        whenever(SubscriptionUtil.isSimHardwareVisible(context)).thenReturn(true)
+        whenever(SubscriptionUtil.getActiveSubscriptions(any())).thenReturn(
+            listOf(
+                SUB_INFO_1,
+                SUB_INFO_2
+            )
+        )
+        var mockSubId = 2
+        controller.init(mockFragment, mockSubId)
+        mockEid = String()
+
+        controller.refreshData(SUB_INFO_2)
+
+        assertThat(preference.isVisible).isEqualTo(false)
+    }
+
+    @Test
+    fun refreshData_getEmptyEid_preferenceSummaryIsExpected() = runBlocking {
+        whenever(SubscriptionUtil.isSimHardwareVisible(context)).thenReturn(true)
+        whenever(SubscriptionUtil.getActiveSubscriptions(any())).thenReturn(
+            listOf(
+                SUB_INFO_1,
+                SUB_INFO_2
+            )
+        )
+        var mockSubId = 2
+        controller.init(mockFragment, mockSubId)
+        mockEid = "test eid"
+        mockEuiccManager.stub {
+            on {eid} doReturn mockEid
+        }
+
+        controller.refreshData(SUB_INFO_2)
+
+        assertThat(preference.summary).isEqualTo(mockEid)
+    }
+
+    @Test
+    fun getAvailabilityStatus_notSimHardwareVisible() {
+        whenever(SubscriptionUtil.isSimHardwareVisible(context)).thenReturn(false)
+
+        val availabilityStatus = controller.availabilityStatus
+
+        assertThat(availabilityStatus).isEqualTo(BasePreferenceController.CONDITIONALLY_UNAVAILABLE)
+    }
+
+    private companion object {
+        const val TEST_KEY = "test_key"
+        const val DISPLAY_NAME_1 = "Sub 1"
+        const val DISPLAY_NAME_2 = "Sub 2"
+
+        val SUB_INFO_1: SubscriptionInfo = SubscriptionInfo.Builder().apply {
+            setId(1)
+            setDisplayName(DISPLAY_NAME_1)
+        }.build()
+
+        val SUB_INFO_2: SubscriptionInfo = SubscriptionInfo.Builder().apply {
+            setId(2)
+            setDisplayName(DISPLAY_NAME_2)
+        }.build()
+
+    }
+}
diff --git a/tests/spa_unit/src/com/android/settings/network/telephony/MobileNetworkImeiPreferenceControllerTest.kt b/tests/spa_unit/src/com/android/settings/network/telephony/MobileNetworkImeiPreferenceControllerTest.kt
new file mode 100644
index 0000000..2f67846
--- /dev/null
+++ b/tests/spa_unit/src/com/android/settings/network/telephony/MobileNetworkImeiPreferenceControllerTest.kt
@@ -0,0 +1,138 @@
+/*
+ * Copyright (C) 2024 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.settings.network.telephony
+
+import android.content.Context
+import android.telephony.SubscriptionInfo
+import android.telephony.TelephonyManager
+import android.telephony.euicc.EuiccManager
+import androidx.fragment.app.Fragment
+import androidx.preference.Preference
+import androidx.preference.PreferenceManager
+import androidx.test.core.app.ApplicationProvider
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import com.android.dx.mockito.inline.extended.ExtendedMockito
+import com.android.internal.telephony.PhoneConstants
+import com.android.settings.core.BasePreferenceController
+import com.android.settings.network.SubscriptionInfoListViewModel
+import com.android.settings.network.SubscriptionUtil
+import com.android.settingslib.CustomDialogPreferenceCompat
+import com.google.common.truth.Truth.assertThat
+import kotlinx.coroutines.runBlocking
+import org.junit.After
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.mockito.MockitoSession
+import org.mockito.kotlin.any
+import org.mockito.kotlin.doReturn
+import org.mockito.kotlin.mock
+import org.mockito.kotlin.spy
+import org.mockito.kotlin.stub
+import org.mockito.kotlin.whenever
+import org.mockito.quality.Strictness
+
+@RunWith(AndroidJUnit4::class)
+class MobileNetworkImeiPreferenceControllerTest {
+    private lateinit var mockSession: MockitoSession
+
+    private val mockViewModels =  mock<Lazy<SubscriptionInfoListViewModel>>()
+    private val mockFragment = mock<Fragment>{
+        val viewmodel = mockViewModels
+    }
+
+    private var mockImei = String()
+    private val mockTelephonyManager = mock<TelephonyManager> {
+        on { uiccCardsInfo } doReturn listOf()
+        on { createForSubscriptionId(any()) } doReturn mock
+        on { currentPhoneType } doReturn TelephonyManager.PHONE_TYPE_GSM
+        on { imei } doReturn mockImei
+        on { meid } doReturn mockImei
+    }
+
+    private val context: Context = spy(ApplicationProvider.getApplicationContext()) {
+        on { getSystemService(TelephonyManager::class.java) } doReturn mockTelephonyManager
+    }
+
+    private val controller = MobileNetworkImeiPreferenceController(context, TEST_KEY)
+    private val preference = Preference(context).apply { key = TEST_KEY }
+    private val preferenceScreen = PreferenceManager(context).createPreferenceScreen(context)
+
+    @Before
+    fun setUp() {
+        mockSession = ExtendedMockito.mockitoSession()
+            .initMocks(this)
+            .mockStatic(SubscriptionUtil::class.java)
+            .strictness(Strictness.LENIENT)
+            .startMocking()
+
+        preferenceScreen.addPreference(preference)
+        controller.displayPreference(preferenceScreen)
+    }
+
+    @After
+    fun tearDown() {
+        mockSession.finishMocking()
+    }
+
+    @Test
+    fun refreshData_getPhoneNumber_preferenceSummaryIsExpected() = runBlocking {
+        whenever(SubscriptionUtil.isSimHardwareVisible(context)).thenReturn(true)
+        whenever(SubscriptionUtil.getActiveSubscriptions(any())).thenReturn(
+            listOf(
+                SUB_INFO_1,
+                SUB_INFO_2
+            )
+        )
+        var mockSubId = 2
+        controller.init(mockFragment, mockSubId)
+        mockImei = "test imei"
+        mockTelephonyManager.stub {
+            on { imei } doReturn mockImei
+        }
+
+        controller.refreshData(SUB_INFO_2)
+
+        assertThat(preference.summary).isEqualTo(mockImei)
+    }
+
+    @Test
+    fun getAvailabilityStatus_notSimHardwareVisible() {
+        whenever(SubscriptionUtil.isSimHardwareVisible(context)).thenReturn(false)
+
+        val availabilityStatus = controller.availabilityStatus
+
+        assertThat(availabilityStatus).isEqualTo(BasePreferenceController.CONDITIONALLY_UNAVAILABLE)
+    }
+
+    private companion object {
+        const val TEST_KEY = "test_key"
+        const val DISPLAY_NAME_1 = "Sub 1"
+        const val DISPLAY_NAME_2 = "Sub 2"
+
+        val SUB_INFO_1: SubscriptionInfo = SubscriptionInfo.Builder().apply {
+            setId(1)
+            setDisplayName(DISPLAY_NAME_1)
+        }.build()
+
+        val SUB_INFO_2: SubscriptionInfo = SubscriptionInfo.Builder().apply {
+            setId(2)
+            setDisplayName(DISPLAY_NAME_2)
+        }.build()
+
+    }
+}
diff --git a/tests/spa_unit/src/com/android/settings/network/telephony/MobileNetworkPhoneNumberPreferenceControllerTest.kt b/tests/spa_unit/src/com/android/settings/network/telephony/MobileNetworkPhoneNumberPreferenceControllerTest.kt
new file mode 100644
index 0000000..38c47c2
--- /dev/null
+++ b/tests/spa_unit/src/com/android/settings/network/telephony/MobileNetworkPhoneNumberPreferenceControllerTest.kt
@@ -0,0 +1,140 @@
+/*
+ * Copyright (C) 2024 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.settings.network.telephony
+
+import android.content.Context
+import android.telephony.SubscriptionInfo
+import androidx.fragment.app.Fragment
+import androidx.preference.Preference
+import androidx.preference.PreferenceManager
+import androidx.test.core.app.ApplicationProvider
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import com.android.dx.mockito.inline.extended.ExtendedMockito
+import com.android.settings.R
+import com.android.settings.core.BasePreferenceController
+import com.android.settings.network.SubscriptionInfoListViewModel
+import com.android.settings.network.SubscriptionUtil
+import com.google.common.truth.Truth.assertThat
+import kotlinx.coroutines.runBlocking
+import org.junit.After
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.mockito.MockitoSession
+import org.mockito.kotlin.any
+import org.mockito.kotlin.mock
+import org.mockito.kotlin.whenever
+import org.mockito.quality.Strictness
+
+@RunWith(AndroidJUnit4::class)
+class MobileNetworkPhoneNumberPreferenceControllerTest {
+    private lateinit var mockSession: MockitoSession
+
+    private val mockViewModels =  mock<Lazy<SubscriptionInfoListViewModel>>()
+    private val mockFragment = mock<Fragment>{
+        val viewmodel = mockViewModels
+    }
+
+    private var mockPhoneNumber = String()
+    private val context: Context = ApplicationProvider.getApplicationContext()
+    private val controller = MobileNetworkPhoneNumberPreferenceController(context, TEST_KEY)
+    private val preference = Preference(context).apply { key = TEST_KEY }
+    private val preferenceScreen = PreferenceManager(context).createPreferenceScreen(context)
+
+    @Before
+    fun setUp() {
+        mockSession = ExtendedMockito.mockitoSession()
+            .initMocks(this)
+            .mockStatic(SubscriptionUtil::class.java)
+            .strictness(Strictness.LENIENT)
+            .startMocking()
+
+        preferenceScreen.addPreference(preference)
+        controller.displayPreference(preferenceScreen)
+
+        whenever(SubscriptionUtil.getBidiFormattedPhoneNumber(any(),any())).thenReturn(mockPhoneNumber)
+    }
+
+    @After
+    fun tearDown() {
+        mockSession.finishMocking()
+    }
+
+    @Test
+    fun refreshData_getEmptyPhoneNumber_preferenceIsNotVisible() = runBlocking {
+        whenever(SubscriptionUtil.isSimHardwareVisible(context)).thenReturn(true)
+        whenever(SubscriptionUtil.getActiveSubscriptions(any())).thenReturn(
+            listOf(
+                SUB_INFO_1,
+                SUB_INFO_2
+            )
+        )
+        var mockSubId = 2
+        controller.init(mockFragment, mockSubId)
+        mockPhoneNumber = String()
+
+        controller.refreshData(SUB_INFO_2)
+
+        assertThat(preference.summary).isEqualTo(
+            context.getString(R.string.device_info_default))
+    }
+
+    @Test
+    fun refreshData_getPhoneNumber_preferenceSummaryIsExpected() = runBlocking {
+        whenever(SubscriptionUtil.isSimHardwareVisible(context)).thenReturn(true)
+        whenever(SubscriptionUtil.getActiveSubscriptions(any())).thenReturn(
+            listOf(
+                SUB_INFO_1,
+                SUB_INFO_2
+            )
+        )
+        var mockSubId = 2
+        controller.init(mockFragment, mockSubId)
+        mockPhoneNumber = "test phone number"
+        whenever(SubscriptionUtil.getBidiFormattedPhoneNumber(any(),any())).thenReturn(mockPhoneNumber)
+
+        controller.refreshData(SUB_INFO_2)
+
+        assertThat(preference.summary).isEqualTo(mockPhoneNumber)
+    }
+
+    @Test
+    fun getAvailabilityStatus_notSimHardwareVisible() {
+        whenever(SubscriptionUtil.isSimHardwareVisible(context)).thenReturn(false)
+
+        val availabilityStatus = controller.availabilityStatus
+
+        assertThat(availabilityStatus).isEqualTo(BasePreferenceController.CONDITIONALLY_UNAVAILABLE)
+    }
+
+    private companion object {
+        const val TEST_KEY = "test_key"
+        const val DISPLAY_NAME_1 = "Sub 1"
+        const val DISPLAY_NAME_2 = "Sub 2"
+
+        val SUB_INFO_1: SubscriptionInfo = SubscriptionInfo.Builder().apply {
+            setId(1)
+            setDisplayName(DISPLAY_NAME_1)
+        }.build()
+
+        val SUB_INFO_2: SubscriptionInfo = SubscriptionInfo.Builder().apply {
+            setId(2)
+            setDisplayName(DISPLAY_NAME_2)
+        }.build()
+
+    }
+}
diff --git a/tests/spa_unit/src/com/android/settings/network/telephony/MobileNetworkSpnPreferenceControllerTest.kt b/tests/spa_unit/src/com/android/settings/network/telephony/MobileNetworkSpnPreferenceControllerTest.kt
new file mode 100644
index 0000000..f5592c1
--- /dev/null
+++ b/tests/spa_unit/src/com/android/settings/network/telephony/MobileNetworkSpnPreferenceControllerTest.kt
@@ -0,0 +1,108 @@
+/*
+ * Copyright (C) 2024 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.settings.network.telephony
+
+import android.content.Context
+import android.telephony.SubscriptionInfo
+import android.telephony.TelephonyManager
+import android.telephony.euicc.EuiccManager
+import androidx.fragment.app.Fragment
+import androidx.preference.Preference
+import androidx.preference.PreferenceManager
+import androidx.test.core.app.ApplicationProvider
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import com.android.dx.mockito.inline.extended.ExtendedMockito
+import com.android.settings.core.BasePreferenceController
+import com.android.settings.network.SubscriptionInfoListViewModel
+import com.android.settings.network.SubscriptionUtil
+import com.google.common.truth.Truth.assertThat
+import kotlinx.coroutines.runBlocking
+import org.junit.After
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.mockito.MockitoSession
+import org.mockito.kotlin.any
+import org.mockito.kotlin.doReturn
+import org.mockito.kotlin.mock
+import org.mockito.kotlin.spy
+import org.mockito.kotlin.whenever
+import org.mockito.quality.Strictness
+
+@RunWith(AndroidJUnit4::class)
+class MobileNetworkSpnPreferenceControllerTest {
+    private lateinit var mockSession: MockitoSession
+
+    private val mockViewModels =  mock<Lazy<SubscriptionInfoListViewModel>>()
+    private val mockFragment = mock<Fragment>{
+        val viewmodel = mockViewModels
+    }
+
+    private val context: Context = ApplicationProvider.getApplicationContext()
+    private val controller = MobileNetworkSpnPreferenceController(context, TEST_KEY)
+    private val preference = Preference(context).apply { key = TEST_KEY }
+    private val preferenceScreen = PreferenceManager(context).createPreferenceScreen(context)
+
+    @Before
+    fun setUp() {
+        mockSession = ExtendedMockito.mockitoSession()
+            .initMocks(this)
+            .mockStatic(SubscriptionUtil::class.java)
+            .strictness(Strictness.LENIENT)
+            .startMocking()
+
+        preferenceScreen.addPreference(preference)
+        controller.displayPreference(preferenceScreen)
+    }
+
+    @After
+    fun tearDown() {
+        mockSession.finishMocking()
+    }
+
+    @Test
+    fun refreshData_getCarrierName_preferenceSummaryIsExpected() = runBlocking {
+        var testList = listOf(
+            SUB_INFO_1,
+            SUB_INFO_2
+        )
+        whenever(SubscriptionUtil.getActiveSubscriptions(any())).thenReturn(testList)
+        var mockSubId = 2
+        controller.init(mockFragment, mockSubId)
+
+        controller.refreshData(testList)
+
+        assertThat(preference.summary).isEqualTo(CARRIER_NAME_2)
+    }
+
+    private companion object {
+        const val TEST_KEY = "test_key"
+        const val CARRIER_NAME_1 = "Sub 1"
+        const val CARRIER_NAME_2 = "Sub 2"
+
+        val SUB_INFO_1: SubscriptionInfo = SubscriptionInfo.Builder().apply {
+            setId(1)
+            setCarrierName(CARRIER_NAME_1)
+        }.build()
+
+        val SUB_INFO_2: SubscriptionInfo = SubscriptionInfo.Builder().apply {
+            setId(2)
+            setCarrierName(CARRIER_NAME_2)
+        }.build()
+
+    }
+}
diff --git a/tests/unit/src/com/android/settings/deviceinfo/PhoneNumberPreferenceControllerTest.java b/tests/unit/src/com/android/settings/deviceinfo/PhoneNumberPreferenceControllerTest.java
index 5f02b04..9a5399c 100644
--- a/tests/unit/src/com/android/settings/deviceinfo/PhoneNumberPreferenceControllerTest.java
+++ b/tests/unit/src/com/android/settings/deviceinfo/PhoneNumberPreferenceControllerTest.java
@@ -37,7 +37,6 @@
 import androidx.test.core.app.ApplicationProvider;
 import androidx.test.ext.junit.runners.AndroidJUnit4;
 
-import com.android.settings.core.BasePreferenceController;
 import com.android.settings.testutils.ResourcesUtils;
 
 import org.junit.Before;
@@ -89,27 +88,10 @@
         mCategory.setKey(categoryKey);
         mScreen.addPreference(mCategory);
 
-        doReturn(mSubscriptionInfo).when(mController).getSubscriptionInfo(anyInt());
         doReturn(mSecondPreference).when(mController).createNewPreference(mContext);
     }
 
     @Test
-    public void getAvailabilityStatus_isVoiceCapable_shouldBeAVAILABLE() {
-        when(mTelephonyManager.isVoiceCapable()).thenReturn(true);
-
-        assertThat(mController.getAvailabilityStatus()).isEqualTo(
-                BasePreferenceController.AVAILABLE);
-    }
-
-    @Test
-    public void getAvailabilityStatus_isNotVoiceCapable_shouldBeUNSUPPORTED_ON_DEVICE() {
-        when(mTelephonyManager.isVoiceCapable()).thenReturn(false);
-
-        assertThat(mController.getAvailabilityStatus()).isEqualTo(
-                BasePreferenceController.UNSUPPORTED_ON_DEVICE);
-    }
-
-    @Test
     public void displayPreference_multiSim_shouldAddSecondPreference() {
         when(mTelephonyManager.getPhoneCount()).thenReturn(2);
 
@@ -123,6 +105,7 @@
     @Test
     public void updateState_singleSim_shouldUpdateTitleAndPhoneNumber() {
         final String phoneNumber = "1111111111";
+        doReturn(mSubscriptionInfo).when(mController).getSubscriptionInfo(anyInt());
         doReturn(phoneNumber).when(mController).getFormattedPhoneNumber(mSubscriptionInfo);
         when(mTelephonyManager.getPhoneCount()).thenReturn(1);
         mController.displayPreference(mScreen);
@@ -136,6 +119,7 @@
     @Test
     public void updateState_multiSim_shouldUpdateTitleAndPhoneNumberOfMultiplePreferences() {
         final String phoneNumber = "1111111111";
+        doReturn(mSubscriptionInfo).when(mController).getSubscriptionInfo(anyInt());
         doReturn(phoneNumber).when(mController).getFormattedPhoneNumber(mSubscriptionInfo);
         when(mTelephonyManager.getPhoneCount()).thenReturn(2);
         mController.displayPreference(mScreen);
@@ -153,11 +137,11 @@
     @Test
     public void getSummary_cannotGetActiveSubscriptionInfo_shouldShowUnknown() {
         when(mSubscriptionManager.getActiveSubscriptionInfoList()).thenReturn(null);
+        mController.displayPreference(mScreen);
 
-        CharSequence primaryNumber = mController.getSummary();
+        mController.updateState(mPreference);
 
-        assertThat(primaryNumber).isNotNull();
-        assertThat(primaryNumber).isEqualTo(ResourcesUtils.getResourcesString(
+        verify(mPreference).setSummary(ResourcesUtils.getResourcesString(
                 mContext, "device_info_default"));
     }
 
@@ -166,9 +150,10 @@
         List<SubscriptionInfo> infos = new ArrayList<>();
         when(mSubscriptionManager.getActiveSubscriptionInfoList()).thenReturn(infos);
 
-        CharSequence primaryNumber = mController.getSummary();
+        mController.displayPreference(mScreen);
+        mController.updateState(mPreference);
 
-        assertThat(primaryNumber).isEqualTo(ResourcesUtils.getResourcesString(
+        verify(mPreference).setSummary(ResourcesUtils.getResourcesString(
                 mContext, "device_info_default"));
     }
 }
diff --git a/tests/unit/src/com/android/settings/network/telephony/MobileDataPreferenceControllerTest.java b/tests/unit/src/com/android/settings/network/telephony/MobileDataPreferenceControllerTest.java
index 4d48025..11a490e 100644
--- a/tests/unit/src/com/android/settings/network/telephony/MobileDataPreferenceControllerTest.java
+++ b/tests/unit/src/com/android/settings/network/telephony/MobileDataPreferenceControllerTest.java
@@ -98,6 +98,7 @@
         doReturn(mTelephonyManager).when(mContext).getSystemService(Context.TELEPHONY_SERVICE);
 
         when(mContext.getSystemService(SubscriptionManager.class)).thenReturn(mSubscriptionManager);
+        when(mSubscriptionManager.createForAllUserProfiles()).thenReturn(mSubscriptionManager);
         doReturn(mTelephonyManager).when(mTelephonyManager).createForSubscriptionId(SUB_ID);
         doReturn(mInvalidTelephonyManager).when(mTelephonyManager).createForSubscriptionId(
                 SubscriptionManager.INVALID_SUBSCRIPTION_ID);
@@ -182,7 +183,8 @@
 
         mController.onPreferenceChange(mPreference, true);
 
-        verify(mTelephonyManager).setDataEnabled(true);
+        verify(mTelephonyManager).setDataEnabledForReason(TelephonyManager.DATA_ENABLED_REASON_USER
+                ,true);
     }
 
     @Test
@@ -195,7 +197,8 @@
 
         mController.onPreferenceChange(mPreference, true);
 
-        verify(mTelephonyManager).setDataEnabled(true);
+        verify(mTelephonyManager).setDataEnabledForReason(TelephonyManager.DATA_ENABLED_REASON_USER
+                ,true);
     }
 
     @Test