diff --git a/packages/SystemUI/Android.bp b/packages/SystemUI/Android.bp
index b88ae37..b358bdc 100644
--- a/packages/SystemUI/Android.bp
+++ b/packages/SystemUI/Android.bp
@@ -285,6 +285,7 @@
         "tests/src/**/systemui/statusbar/phone/KeyguardClockPositionAlgorithmTest.java",
         "tests/src/**/systemui/shared/system/RemoteTransitionTest.java",
         "tests/src/**/systemui/qs/tiles/dialog/InternetDetailsContentControllerTest.java",
+        "tests/src/**/systemui/qs/tiles/dialog/InternetDetailsContentManagerTest.kt",
         "tests/src/**/systemui/qs/external/TileLifecycleManagerTest.java",
         "tests/src/**/systemui/ScreenDecorationsTest.java",
         "tests/src/**/systemui/statusbar/policy/BatteryControllerStartableTest.java",
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/InternetDetailsContentController.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/InternetDetailsContentController.java
index 23210ef..340cb68 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/InternetDetailsContentController.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/InternetDetailsContentController.java
@@ -373,7 +373,6 @@
         mConnectivityManager.setAirplaneMode(false);
     }
 
-    @VisibleForTesting
     protected int getDefaultDataSubscriptionId() {
         return mSubscriptionManager.getDefaultDataSubscriptionId();
     }
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/InternetDetailsContentManager.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/InternetDetailsContentManager.kt
new file mode 100644
index 0000000..c64532a
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/InternetDetailsContentManager.kt
@@ -0,0 +1,991 @@
+/*
+ * 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.systemui.qs.tiles.dialog
+
+import android.app.AlertDialog
+import android.content.Context
+import android.content.DialogInterface
+import android.graphics.drawable.Drawable
+import android.net.Network
+import android.net.NetworkCapabilities
+import android.os.Handler
+import android.telephony.ServiceState
+import android.telephony.SignalStrength
+import android.telephony.SubscriptionManager
+import android.telephony.TelephonyDisplayInfo
+import android.text.Html
+import android.text.Layout
+import android.text.TextUtils
+import android.text.method.LinkMovementMethod
+import android.util.Log
+import android.view.View
+import android.view.ViewStub
+import android.view.WindowManager
+import android.widget.Button
+import android.widget.ImageView
+import android.widget.LinearLayout
+import android.widget.ProgressBar
+import android.widget.Switch
+import android.widget.TextView
+import androidx.annotation.MainThread
+import androidx.annotation.WorkerThread
+import androidx.lifecycle.Lifecycle
+import androidx.lifecycle.LifecycleOwner
+import androidx.lifecycle.LifecycleRegistry
+import androidx.lifecycle.MutableLiveData
+import androidx.recyclerview.widget.LinearLayoutManager
+import androidx.recyclerview.widget.RecyclerView
+import com.android.internal.logging.UiEvent
+import com.android.internal.logging.UiEventLogger
+import com.android.internal.telephony.flags.Flags
+import com.android.settingslib.satellite.SatelliteDialogUtils.TYPE_IS_WIFI
+import com.android.settingslib.satellite.SatelliteDialogUtils.mayStartSatelliteWarningDialog
+import com.android.settingslib.wifi.WifiEnterpriseRestrictionUtils
+import com.android.systemui.Prefs
+import com.android.systemui.accessibility.floatingmenu.AnnotationLinkSpan
+import com.android.systemui.animation.DialogTransitionAnimator
+import com.android.systemui.dagger.qualifiers.Background
+import com.android.systemui.dagger.qualifiers.Main
+import com.android.systemui.qs.flags.QsDetailedView
+import com.android.systemui.res.R
+import com.android.systemui.statusbar.phone.SystemUIDialog
+import com.android.systemui.statusbar.policy.KeyguardStateController
+import com.android.wifitrackerlib.WifiEntry
+import com.google.common.annotations.VisibleForTesting
+import dagger.assisted.Assisted
+import dagger.assisted.AssistedFactory
+import dagger.assisted.AssistedInject
+import java.util.concurrent.Executor
+import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.Job
+
+/**
+ * View content for the Internet tile details that handles all UI interactions and state management.
+ *
+ * @param internetDialog non-null if the details should be shown as part of a dialog and null
+ *   otherwise.
+ */
+// TODO: b/377388104 Make this content for details view only.
+class InternetDetailsContentManager
+@AssistedInject
+constructor(
+    private val internetDetailsContentController: InternetDetailsContentController,
+    @Assisted(CAN_CONFIG_MOBILE_DATA) private val canConfigMobileData: Boolean,
+    @Assisted(CAN_CONFIG_WIFI) private val canConfigWifi: Boolean,
+    @Assisted private val coroutineScope: CoroutineScope,
+    @Assisted private var context: Context,
+    @Assisted private var internetDialog: SystemUIDialog?,
+    private val uiEventLogger: UiEventLogger,
+    private val dialogTransitionAnimator: DialogTransitionAnimator,
+    @Main private val handler: Handler,
+    @Background private val backgroundExecutor: Executor,
+    private val keyguard: KeyguardStateController,
+) {
+    // Lifecycle
+    private lateinit var lifecycleRegistry: LifecycleRegistry
+    @VisibleForTesting internal var lifecycleOwner: LifecycleOwner? = null
+    @VisibleForTesting internal val internetContentData = MutableLiveData<InternetContent>()
+    @VisibleForTesting internal var connectedWifiEntry: WifiEntry? = null
+    @VisibleForTesting internal var isProgressBarVisible = false
+
+    // UI Components
+    private lateinit var contentView: View
+    private lateinit var internetDialogTitleView: TextView
+    private lateinit var internetDialogSubTitleView: TextView
+    private lateinit var divider: View
+    private lateinit var progressBar: ProgressBar
+    private lateinit var ethernetLayout: LinearLayout
+    private lateinit var mobileNetworkLayout: LinearLayout
+    private var secondaryMobileNetworkLayout: LinearLayout? = null
+    private lateinit var turnWifiOnLayout: LinearLayout
+    private lateinit var wifiToggleTitleTextView: TextView
+    private lateinit var wifiScanNotifyLayout: LinearLayout
+    private lateinit var wifiScanNotifyTextView: TextView
+    private lateinit var connectedWifiListLayout: LinearLayout
+    private lateinit var connectedWifiIcon: ImageView
+    private lateinit var connectedWifiTitleTextView: TextView
+    private lateinit var connectedWifiSummaryTextView: TextView
+    private lateinit var wifiSettingsIcon: ImageView
+    private lateinit var wifiRecyclerView: RecyclerView
+    private lateinit var seeAllLayout: LinearLayout
+    private lateinit var signalIcon: ImageView
+    private lateinit var mobileTitleTextView: TextView
+    private lateinit var mobileSummaryTextView: TextView
+    private lateinit var airplaneModeSummaryTextView: TextView
+    private lateinit var mobileDataToggle: Switch
+    private lateinit var mobileToggleDivider: View
+    private lateinit var wifiToggle: Switch
+    private lateinit var shareWifiButton: Button
+    private lateinit var airplaneModeButton: Button
+    private var alertDialog: AlertDialog? = null
+    private lateinit var doneButton: Button
+
+    private val canChangeWifiState =
+        WifiEnterpriseRestrictionUtils.isChangeWifiStateAllowed(context)
+    private var wifiNetworkHeight = 0
+    private var backgroundOn: Drawable? = null
+    private var backgroundOff: Drawable? = null
+    private var clickJob: Job? = null
+    private var defaultDataSubId = internetDetailsContentController.defaultDataSubscriptionId
+    @VisibleForTesting
+    internal var adapter = InternetAdapter(internetDetailsContentController, coroutineScope)
+    @VisibleForTesting internal var wifiEntriesCount: Int = 0
+    @VisibleForTesting internal var hasMoreWifiEntries: Boolean = false
+
+    @AssistedFactory
+    interface Factory {
+        fun create(
+            @Assisted(CAN_CONFIG_MOBILE_DATA) canConfigMobileData: Boolean,
+            @Assisted(CAN_CONFIG_WIFI) canConfigWifi: Boolean,
+            coroutineScope: CoroutineScope,
+            context: Context,
+            internetDialog: SystemUIDialog?,
+        ): InternetDetailsContentManager
+    }
+
+    /**
+     * Binds the content manager to the provided content view.
+     *
+     * This method initializes the lifecycle, views, click listeners, and UI of the details content.
+     * It also updates the UI with the current Wi-Fi network information.
+     *
+     * @param contentView The view to which the content manager should be bound.
+     */
+    fun bind(contentView: View) {
+        if (DEBUG) {
+            Log.d(TAG, "Bind InternetDetailsContentManager")
+        }
+
+        this.contentView = contentView
+
+        initializeLifecycle()
+        initializeViews()
+        updateDetailsUI(getStartingInternetContent())
+        initializeAndConfigure()
+    }
+
+    /**
+     * Initializes the LifecycleRegistry if it hasn't been initialized yet. It sets the initial
+     * state of the LifecycleRegistry to Lifecycle.State.CREATED.
+     */
+    fun initializeLifecycle() {
+        if (!::lifecycleRegistry.isInitialized) {
+            lifecycleOwner =
+                object : LifecycleOwner {
+                    override val lifecycle: Lifecycle
+                        get() = lifecycleRegistry
+                }
+            lifecycleRegistry = LifecycleRegistry(lifecycleOwner!!)
+        }
+        lifecycleRegistry.currentState = Lifecycle.State.CREATED
+    }
+
+    private fun initializeViews() {
+        // Set accessibility properties
+        contentView.accessibilityPaneTitle =
+            context.getText(R.string.accessibility_desc_quick_settings)
+
+        // Get dimension resources
+        wifiNetworkHeight =
+            context.resources.getDimensionPixelSize(R.dimen.internet_dialog_wifi_network_height)
+
+        // Initialize LiveData observer
+        internetContentData.observe(lifecycleOwner!!) { internetContent ->
+            updateDetailsUI(internetContent)
+        }
+
+        // Network layouts
+        internetDialogTitleView = contentView.requireViewById(R.id.internet_dialog_title)
+        internetDialogSubTitleView = contentView.requireViewById(R.id.internet_dialog_subtitle)
+        divider = contentView.requireViewById(R.id.divider)
+        progressBar = contentView.requireViewById(R.id.wifi_searching_progress)
+
+        // Set wifi, mobile and ethernet layouts
+        setWifiLayout()
+        setMobileLayout()
+        ethernetLayout = contentView.requireViewById(R.id.ethernet_layout)
+
+        // Done button is only visible for the dialog view
+        doneButton = contentView.requireViewById(R.id.done_button)
+        if (internetDialog == null) {
+            doneButton.visibility = View.GONE
+        } else {
+            // Set done button if qs details view is not enabled.
+            doneButton.setOnClickListener { internetDialog!!.dismiss() }
+        }
+
+        // Share WiFi
+        shareWifiButton = contentView.requireViewById(R.id.share_wifi_button)
+        shareWifiButton.setOnClickListener { view ->
+            if (
+                internetDetailsContentController.mayLaunchShareWifiSettings(
+                    connectedWifiEntry,
+                    view,
+                )
+            ) {
+                uiEventLogger.log(InternetDetailsEvent.SHARE_WIFI_QS_BUTTON_CLICKED)
+            }
+        }
+
+        // Airplane mode
+        airplaneModeButton = contentView.requireViewById(R.id.apm_button)
+        airplaneModeButton.setOnClickListener {
+            internetDetailsContentController.setAirplaneModeDisabled()
+        }
+        airplaneModeSummaryTextView = contentView.requireViewById(R.id.airplane_mode_summary)
+
+        // Background drawables
+        backgroundOn = context.getDrawable(R.drawable.settingslib_switch_bar_bg_on)
+        backgroundOff = context.getDrawable(R.drawable.internet_dialog_selected_effect)
+    }
+
+    private fun setWifiLayout() {
+        // Initialize Wi-Fi related views
+        turnWifiOnLayout = contentView.requireViewById(R.id.turn_on_wifi_layout)
+        wifiToggleTitleTextView = contentView.requireViewById(R.id.wifi_toggle_title)
+        wifiScanNotifyLayout = contentView.requireViewById(R.id.wifi_scan_notify_layout)
+        wifiScanNotifyTextView = contentView.requireViewById(R.id.wifi_scan_notify_text)
+        connectedWifiListLayout = contentView.requireViewById(R.id.wifi_connected_layout)
+        connectedWifiIcon = contentView.requireViewById(R.id.wifi_connected_icon)
+        connectedWifiTitleTextView = contentView.requireViewById(R.id.wifi_connected_title)
+        connectedWifiSummaryTextView = contentView.requireViewById(R.id.wifi_connected_summary)
+        wifiSettingsIcon = contentView.requireViewById(R.id.wifi_settings_icon)
+        wifiToggle = contentView.requireViewById(R.id.wifi_toggle)
+        wifiRecyclerView =
+            contentView.requireViewById<RecyclerView>(R.id.wifi_list_layout).apply {
+                layoutManager = LinearLayoutManager(context)
+                adapter = this@InternetDetailsContentManager.adapter
+            }
+        seeAllLayout = contentView.requireViewById(R.id.see_all_layout)
+
+        // Set click listeners for Wi-Fi related views
+        wifiToggle.setOnClickListener {
+            val isChecked = wifiToggle.isChecked
+            handleWifiToggleClicked(isChecked)
+        }
+        connectedWifiListLayout.setOnClickListener(this::onClickConnectedWifi)
+        seeAllLayout.setOnClickListener(this::onClickSeeMoreButton)
+    }
+
+    private fun setMobileLayout() {
+        // Initialize mobile data related views
+        mobileNetworkLayout = contentView.requireViewById(R.id.mobile_network_layout)
+        signalIcon = contentView.requireViewById(R.id.signal_icon)
+        mobileTitleTextView = contentView.requireViewById(R.id.mobile_title)
+        mobileSummaryTextView = contentView.requireViewById(R.id.mobile_summary)
+        mobileDataToggle = contentView.requireViewById(R.id.mobile_toggle)
+        mobileToggleDivider = contentView.requireViewById(R.id.mobile_toggle_divider)
+
+        // Set click listeners for mobile data related views
+        mobileNetworkLayout.setOnClickListener {
+            val autoSwitchNonDdsSubId: Int =
+                internetDetailsContentController.getActiveAutoSwitchNonDdsSubId()
+            if (autoSwitchNonDdsSubId != SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
+                showTurnOffAutoDataSwitchDialog(autoSwitchNonDdsSubId)
+            }
+            internetDetailsContentController.connectCarrierNetwork()
+        }
+
+        // Mobile data toggle
+        mobileDataToggle.setOnClickListener {
+            val isChecked = mobileDataToggle.isChecked
+            if (!isChecked && shouldShowMobileDialog()) {
+                mobileDataToggle.isChecked = true
+                showTurnOffMobileDialog()
+            } else if (internetDetailsContentController.isMobileDataEnabled != isChecked) {
+                internetDetailsContentController.setMobileDataEnabled(
+                    context,
+                    defaultDataSubId,
+                    isChecked,
+                    false,
+                )
+            }
+        }
+    }
+
+    /**
+     * This function ensures the component is in the RESUMED state and sets up the internet details
+     * content controller.
+     *
+     * If the component is already in the RESUMED state, this function does nothing.
+     */
+    fun initializeAndConfigure() {
+        // If the current state is RESUMED, it's already initialized.
+        if (lifecycleRegistry.currentState == Lifecycle.State.RESUMED) {
+            return
+        }
+
+        lifecycleRegistry.currentState = Lifecycle.State.RESUMED
+        internetDetailsContentController.onStart(internetDetailsCallback, canConfigWifi)
+        if (!canConfigWifi) {
+            hideWifiViews()
+        }
+    }
+
+    private fun getDialogTitleText(): CharSequence {
+        return internetDetailsContentController.getDialogTitleText()
+    }
+
+    private fun updateDetailsUI(internetContent: InternetContent) {
+        if (DEBUG) {
+            Log.d(TAG, "updateDetailsUI ")
+        }
+        if (QsDetailedView.isEnabled) {
+            internetDialogTitleView.visibility = View.GONE
+            internetDialogSubTitleView.visibility = View.GONE
+        } else {
+            internetDialogTitleView.text = internetContent.internetDialogTitleString
+            internetDialogSubTitleView.text = internetContent.internetDialogSubTitle
+        }
+        airplaneModeButton.visibility =
+            if (internetContent.isAirplaneModeEnabled) View.VISIBLE else View.GONE
+
+        updateEthernetUI(internetContent)
+        updateMobileUI(internetContent)
+        updateWifiUI(internetContent)
+    }
+
+    private fun getStartingInternetContent(): InternetContent {
+        return InternetContent(
+            internetDialogTitleString = getDialogTitleText(),
+            internetDialogSubTitle = getSubtitleText(),
+            isWifiEnabled = internetDetailsContentController.isWifiEnabled,
+            isDeviceLocked = internetDetailsContentController.isDeviceLocked,
+        )
+    }
+
+    private fun getSubtitleText(): String {
+        return internetDetailsContentController.getSubtitleText(isProgressBarVisible).toString()
+    }
+
+    @VisibleForTesting
+    internal fun hideWifiViews() {
+        setProgressBarVisible(false)
+        turnWifiOnLayout.visibility = View.GONE
+        connectedWifiListLayout.visibility = View.GONE
+        wifiRecyclerView.visibility = View.GONE
+        seeAllLayout.visibility = View.GONE
+        shareWifiButton.visibility = View.GONE
+    }
+
+    private fun setProgressBarVisible(visible: Boolean) {
+        if (isProgressBarVisible == visible) {
+            return
+        }
+
+        // Set the indeterminate value from false to true each time to ensure that the progress bar
+        // resets its animation and starts at the leftmost starting point each time it is displayed.
+        isProgressBarVisible = visible
+        progressBar.visibility = if (visible) View.VISIBLE else View.GONE
+        progressBar.isIndeterminate = visible
+        divider.visibility = if (visible) View.GONE else View.VISIBLE
+        internetDialogSubTitleView.text = getSubtitleText()
+    }
+
+    private fun showTurnOffAutoDataSwitchDialog(subId: Int) {
+        var carrierName: CharSequence? = getMobileNetworkTitle(defaultDataSubId)
+        if (TextUtils.isEmpty(carrierName)) {
+            carrierName = getDefaultCarrierName()
+        }
+        alertDialog =
+            AlertDialog.Builder(context)
+                .setTitle(context.getString(R.string.auto_data_switch_disable_title, carrierName))
+                .setMessage(R.string.auto_data_switch_disable_message)
+                .setNegativeButton(R.string.auto_data_switch_dialog_negative_button) { _, _ -> }
+                .setPositiveButton(R.string.auto_data_switch_dialog_positive_button) { _, _ ->
+                    internetDetailsContentController.setAutoDataSwitchMobileDataPolicy(
+                        subId,
+                        /* enable= */ false,
+                    )
+                    secondaryMobileNetworkLayout?.visibility = View.GONE
+                }
+                .create()
+        alertDialog!!.window?.setType(WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG)
+        SystemUIDialog.setShowForAllUsers(alertDialog, true)
+        SystemUIDialog.registerDismissListener(alertDialog)
+        SystemUIDialog.setWindowOnTop(alertDialog, keyguard.isShowing())
+        if (QsDetailedView.isEnabled) {
+            alertDialog!!.show()
+        } else {
+            dialogTransitionAnimator.showFromDialog(alertDialog!!, internetDialog!!, null, false)
+            Log.e(TAG, "Internet dialog is shown with the refactor code")
+        }
+    }
+
+    private fun shouldShowMobileDialog(): Boolean {
+        val mobileDataTurnedOff =
+            Prefs.getBoolean(context, Prefs.Key.QS_HAS_TURNED_OFF_MOBILE_DATA, false)
+        return internetDetailsContentController.isMobileDataEnabled && !mobileDataTurnedOff
+    }
+
+    private fun getMobileNetworkTitle(subId: Int): CharSequence {
+        return internetDetailsContentController.getMobileNetworkTitle(subId)
+    }
+
+    private fun showTurnOffMobileDialog() {
+        val context = contentView.context
+        var carrierName: CharSequence? = getMobileNetworkTitle(defaultDataSubId)
+        val isInService: Boolean =
+            internetDetailsContentController.isVoiceStateInService(defaultDataSubId)
+        if (TextUtils.isEmpty(carrierName) || !isInService) {
+            carrierName = getDefaultCarrierName()
+        }
+        alertDialog =
+            AlertDialog.Builder(context)
+                .setTitle(R.string.mobile_data_disable_title)
+                .setMessage(context.getString(R.string.mobile_data_disable_message, carrierName))
+                .setNegativeButton(android.R.string.cancel) { _: DialogInterface?, _: Int -> }
+                .setPositiveButton(
+                    com.android.internal.R.string.alert_windows_notification_turn_off_action
+                ) { _: DialogInterface?, _: Int ->
+                    internetDetailsContentController.setMobileDataEnabled(
+                        context,
+                        defaultDataSubId,
+                        false,
+                        false,
+                    )
+                    mobileDataToggle.isChecked = false
+                    Prefs.putBoolean(context, Prefs.Key.QS_HAS_TURNED_OFF_MOBILE_DATA, true)
+                }
+                .create()
+        alertDialog!!.window?.setType(WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG)
+        SystemUIDialog.setShowForAllUsers(alertDialog, true)
+        SystemUIDialog.registerDismissListener(alertDialog)
+        SystemUIDialog.setWindowOnTop(alertDialog, keyguard.isShowing())
+        if (QsDetailedView.isEnabled) {
+            alertDialog!!.show()
+        } else {
+            dialogTransitionAnimator.showFromDialog(alertDialog!!, internetDialog!!, null, false)
+        }
+    }
+
+    private fun onClickConnectedWifi(view: View?) {
+        if (connectedWifiEntry == null) {
+            return
+        }
+        internetDetailsContentController.launchWifiDetailsSetting(connectedWifiEntry!!.key, view)
+    }
+
+    private fun onClickSeeMoreButton(view: View?) {
+        internetDetailsContentController.launchNetworkSetting(view)
+    }
+
+    private fun handleWifiToggleClicked(isChecked: Boolean) {
+        if (Flags.oemEnabledSatelliteFlag()) {
+            if (clickJob != null && !clickJob!!.isCompleted) {
+                return
+            }
+            clickJob =
+                mayStartSatelliteWarningDialog(contentView.context, coroutineScope, TYPE_IS_WIFI) {
+                    isAllowClick: Boolean ->
+                    if (isAllowClick) {
+                        setWifiEnabled(isChecked)
+                    } else {
+                        wifiToggle.isChecked = !isChecked
+                    }
+                }
+            return
+        }
+        setWifiEnabled(isChecked)
+    }
+
+    private fun setWifiEnabled(isEnabled: Boolean) {
+        if (internetDetailsContentController.isWifiEnabled == isEnabled) {
+            return
+        }
+        internetDetailsContentController.isWifiEnabled = isEnabled
+    }
+
+    @MainThread
+    private fun updateEthernetUI(internetContent: InternetContent) {
+        ethernetLayout.visibility = if (internetContent.hasEthernet) View.VISIBLE else View.GONE
+    }
+
+    private fun updateWifiUI(internetContent: InternetContent) {
+        if (!canConfigWifi) {
+            return
+        }
+
+        updateWifiToggle(internetContent)
+        updateConnectedWifi(internetContent)
+        updateWifiListAndSeeAll(internetContent)
+        updateWifiScanNotify(internetContent)
+    }
+
+    private fun updateMobileUI(internetContent: InternetContent) {
+        if (!internetContent.shouldUpdateMobileNetwork) {
+            return
+        }
+
+        val isNetworkConnected =
+            internetContent.activeNetworkIsCellular || internetContent.isCarrierNetworkActive
+        // 1. Mobile network should be gone if airplane mode ON or the list of active
+        //    subscriptionId is null.
+        // 2. Carrier network should be gone if airplane mode ON and Wi-Fi is OFF.
+        if (DEBUG) {
+            Log.d(
+                TAG,
+                /*msg = */ "updateMobileUI, isCarrierNetworkActive = " +
+                    internetContent.isCarrierNetworkActive,
+            )
+        }
+
+        if (
+            !internetContent.hasActiveSubIdOnDds &&
+                (!internetContent.isWifiEnabled || !internetContent.isCarrierNetworkActive)
+        ) {
+            mobileNetworkLayout.visibility = View.GONE
+            secondaryMobileNetworkLayout?.visibility = View.GONE
+            return
+        }
+
+        mobileNetworkLayout.visibility = View.VISIBLE
+        mobileDataToggle.setChecked(internetDetailsContentController.isMobileDataEnabled)
+        mobileTitleTextView.text = getMobileNetworkTitle(defaultDataSubId)
+        val summary = getMobileNetworkSummary(defaultDataSubId)
+        if (!TextUtils.isEmpty(summary)) {
+            mobileSummaryTextView.text = Html.fromHtml(summary, Html.FROM_HTML_MODE_LEGACY)
+            mobileSummaryTextView.setBreakStrategy(Layout.BREAK_STRATEGY_SIMPLE)
+            mobileSummaryTextView.visibility = View.VISIBLE
+        } else {
+            mobileSummaryTextView.visibility = View.GONE
+        }
+        backgroundExecutor.execute {
+            val drawable = getSignalStrengthDrawable(defaultDataSubId)
+            handler.post { signalIcon.setImageDrawable(drawable) }
+        }
+
+        mobileDataToggle.visibility = if (canConfigMobileData) View.VISIBLE else View.INVISIBLE
+        mobileToggleDivider.visibility = if (canConfigMobileData) View.VISIBLE else View.INVISIBLE
+        val primaryColor =
+            if (isNetworkConnected) R.color.connected_network_primary_color
+            else R.color.disconnected_network_primary_color
+        mobileToggleDivider.setBackgroundColor(context.getColor(primaryColor))
+
+        // Display the info for the non-DDS if it's actively being used
+        val autoSwitchNonDdsSubId: Int = internetContent.activeAutoSwitchNonDdsSubId
+
+        val nonDdsVisibility =
+            if (autoSwitchNonDdsSubId != SubscriptionManager.INVALID_SUBSCRIPTION_ID) View.VISIBLE
+            else View.GONE
+
+        val secondaryRes =
+            if (isNetworkConnected) R.style.TextAppearance_InternetDialog_Secondary_Active
+            else R.style.TextAppearance_InternetDialog_Secondary
+        if (nonDdsVisibility == View.VISIBLE) {
+            // non DDS is the currently active sub, set primary visual for it
+            setNonDDSActive(autoSwitchNonDdsSubId)
+        } else {
+            mobileNetworkLayout.background = if (isNetworkConnected) backgroundOn else backgroundOff
+            mobileTitleTextView.setTextAppearance(
+                if (isNetworkConnected) R.style.TextAppearance_InternetDialog_Active
+                else R.style.TextAppearance_InternetDialog
+            )
+            mobileSummaryTextView.setTextAppearance(secondaryRes)
+        }
+
+        secondaryMobileNetworkLayout?.visibility = nonDdsVisibility
+
+        // Set airplane mode to the summary for carrier network
+        if (internetContent.isAirplaneModeEnabled) {
+            airplaneModeSummaryTextView.apply {
+                visibility = View.VISIBLE
+                text = context.getText(R.string.airplane_mode)
+                setTextAppearance(secondaryRes)
+            }
+        } else {
+            airplaneModeSummaryTextView.visibility = View.GONE
+        }
+    }
+
+    private fun setNonDDSActive(autoSwitchNonDdsSubId: Int) {
+        val stub: ViewStub = contentView.findViewById(R.id.secondary_mobile_network_stub)
+        stub.inflate()
+        secondaryMobileNetworkLayout =
+            contentView.findViewById(R.id.secondary_mobile_network_layout)
+        secondaryMobileNetworkLayout?.setOnClickListener { view: View? ->
+            this.onClickConnectedSecondarySub(view)
+        }
+        secondaryMobileNetworkLayout?.background = backgroundOn
+
+        contentView.requireViewById<TextView>(R.id.secondary_mobile_title).apply {
+            text = getMobileNetworkTitle(autoSwitchNonDdsSubId)
+            setTextAppearance(R.style.TextAppearance_InternetDialog_Active)
+        }
+
+        val summary = getMobileNetworkSummary(autoSwitchNonDdsSubId)
+        contentView.requireViewById<TextView>(R.id.secondary_mobile_summary).apply {
+            if (!TextUtils.isEmpty(summary)) {
+                text = Html.fromHtml(summary, Html.FROM_HTML_MODE_LEGACY)
+                breakStrategy = Layout.BREAK_STRATEGY_SIMPLE
+                setTextAppearance(R.style.TextAppearance_InternetDialog_Active)
+            }
+        }
+
+        val secondarySignalIcon: ImageView = contentView.requireViewById(R.id.secondary_signal_icon)
+        backgroundExecutor.execute {
+            val drawable = getSignalStrengthDrawable(autoSwitchNonDdsSubId)
+            handler.post { secondarySignalIcon.setImageDrawable(drawable) }
+        }
+
+        contentView.requireViewById<ImageView>(R.id.secondary_settings_icon).apply {
+            setColorFilter(context.getColor(R.color.connected_network_primary_color))
+        }
+
+        // set secondary visual for default data sub
+        mobileNetworkLayout.background = backgroundOff
+        mobileTitleTextView.setTextAppearance(R.style.TextAppearance_InternetDialog)
+        mobileSummaryTextView.setTextAppearance(R.style.TextAppearance_InternetDialog_Secondary)
+        signalIcon.setColorFilter(context.getColor(R.color.connected_network_secondary_color))
+    }
+
+    @MainThread
+    private fun updateWifiToggle(internetContent: InternetContent) {
+        if (wifiToggle.isChecked != internetContent.isWifiEnabled) {
+            wifiToggle.isChecked = internetContent.isWifiEnabled
+        }
+        if (internetContent.isDeviceLocked) {
+            wifiToggleTitleTextView.setTextAppearance(
+                if ((connectedWifiEntry != null)) R.style.TextAppearance_InternetDialog_Active
+                else R.style.TextAppearance_InternetDialog
+            )
+        }
+        turnWifiOnLayout.background =
+            if ((internetContent.isDeviceLocked && connectedWifiEntry != null)) backgroundOn
+            else null
+
+        if (!canChangeWifiState && wifiToggle.isEnabled) {
+            wifiToggle.isEnabled = false
+            wifiToggleTitleTextView.isEnabled = false
+            contentView.requireViewById<TextView>(R.id.wifi_toggle_summary).apply {
+                isEnabled = false
+                visibility = View.VISIBLE
+            }
+        }
+    }
+
+    @MainThread
+    private fun updateConnectedWifi(internetContent: InternetContent) {
+        if (
+            !internetContent.isWifiEnabled ||
+                connectedWifiEntry == null ||
+                internetContent.isDeviceLocked
+        ) {
+            connectedWifiListLayout.visibility = View.GONE
+            shareWifiButton.visibility = View.GONE
+            return
+        }
+        connectedWifiListLayout.visibility = View.VISIBLE
+        connectedWifiTitleTextView.text = connectedWifiEntry!!.title
+        connectedWifiSummaryTextView.text = connectedWifiEntry!!.getSummary(false)
+        connectedWifiIcon.setImageDrawable(
+            internetDetailsContentController.getInternetWifiDrawable(connectedWifiEntry!!)
+        )
+        wifiSettingsIcon.setColorFilter(context.getColor(R.color.connected_network_primary_color))
+
+        val canShareWifi =
+            internetDetailsContentController.getConfiguratorQrCodeGeneratorIntentOrNull(
+                connectedWifiEntry
+            ) != null
+        shareWifiButton.visibility = if (canShareWifi) View.VISIBLE else View.GONE
+
+        secondaryMobileNetworkLayout?.visibility = View.GONE
+    }
+
+    @MainThread
+    private fun updateWifiListAndSeeAll(internetContent: InternetContent) {
+        if (!internetContent.isWifiEnabled || internetContent.isDeviceLocked) {
+            wifiRecyclerView.visibility = View.GONE
+            seeAllLayout.visibility = View.GONE
+            return
+        }
+        val wifiListMaxCount = getWifiListMaxCount()
+        if (adapter.itemCount > wifiListMaxCount) {
+            hasMoreWifiEntries = true
+        }
+        adapter.setMaxEntriesCount(wifiListMaxCount)
+        val wifiListMinHeight = wifiNetworkHeight * wifiListMaxCount
+        if (wifiRecyclerView.minimumHeight != wifiListMinHeight) {
+            wifiRecyclerView.minimumHeight = wifiListMinHeight
+        }
+        wifiRecyclerView.visibility = View.VISIBLE
+        seeAllLayout.visibility = if (hasMoreWifiEntries) View.VISIBLE else View.INVISIBLE
+    }
+
+    @MainThread
+    private fun updateWifiScanNotify(internetContent: InternetContent) {
+        if (
+            internetContent.isWifiEnabled ||
+                !internetContent.isWifiScanEnabled ||
+                internetContent.isDeviceLocked
+        ) {
+            wifiScanNotifyLayout.visibility = View.GONE
+            return
+        }
+
+        if (TextUtils.isEmpty(wifiScanNotifyTextView.text)) {
+            val linkInfo =
+                AnnotationLinkSpan.LinkInfo(AnnotationLinkSpan.LinkInfo.DEFAULT_ANNOTATION) {
+                    view: View? ->
+                    internetDetailsContentController.launchWifiScanningSetting(view)
+                }
+            wifiScanNotifyTextView.text =
+                AnnotationLinkSpan.linkify(
+                    context.getText(R.string.wifi_scan_notify_message),
+                    linkInfo,
+                )
+            wifiScanNotifyTextView.movementMethod = LinkMovementMethod.getInstance()
+        }
+        wifiScanNotifyLayout.visibility = View.VISIBLE
+    }
+
+    @VisibleForTesting
+    @MainThread
+    internal fun getWifiListMaxCount(): Int {
+        // Use the maximum count of networks to calculate the remaining count for Wi-Fi networks.
+        var count = MAX_NETWORK_COUNT
+        if (ethernetLayout.visibility == View.VISIBLE) {
+            count -= 1
+        }
+        if (mobileNetworkLayout.visibility == View.VISIBLE) {
+            count -= 1
+        }
+
+        // If the remaining count is greater than the maximum count of the Wi-Fi network, the
+        // maximum count of the Wi-Fi network is used.
+        if (count > InternetDetailsContentController.MAX_WIFI_ENTRY_COUNT) {
+            count = InternetDetailsContentController.MAX_WIFI_ENTRY_COUNT
+        }
+        if (connectedWifiListLayout.visibility == View.VISIBLE) {
+            count -= 1
+        }
+        return count
+    }
+
+    private fun getMobileNetworkSummary(subId: Int): String {
+        return internetDetailsContentController.getMobileNetworkSummary(subId)
+    }
+
+    /** For DSDS auto data switch */
+    private fun onClickConnectedSecondarySub(view: View?) {
+        internetDetailsContentController.launchMobileNetworkSettings(view)
+    }
+
+    private fun getSignalStrengthDrawable(subId: Int): Drawable {
+        return internetDetailsContentController.getSignalStrengthDrawable(subId)
+    }
+
+    /**
+     * Unbinds all listeners and resources associated with the view. This method should be called
+     * when the view is no longer needed.
+     */
+    fun unBind() {
+        if (DEBUG) {
+            Log.d(TAG, "unBind")
+        }
+        lifecycleRegistry.currentState = Lifecycle.State.DESTROYED
+        mobileNetworkLayout.setOnClickListener(null)
+        connectedWifiListLayout.setOnClickListener(null)
+        secondaryMobileNetworkLayout?.setOnClickListener(null)
+        seeAllLayout.setOnClickListener(null)
+        wifiToggle.setOnCheckedChangeListener(null)
+        doneButton.setOnClickListener(null)
+        shareWifiButton.setOnClickListener(null)
+        airplaneModeButton.setOnClickListener(null)
+        internetDetailsContentController.onStop()
+    }
+
+    /**
+     * Update the internet details content when receiving the callback.
+     *
+     * @param shouldUpdateMobileNetwork `true` for update the mobile network layout, otherwise
+     *   `false`.
+     */
+    @VisibleForTesting
+    internal fun updateContent(shouldUpdateMobileNetwork: Boolean) {
+        backgroundExecutor.execute {
+            internetContentData.postValue(getInternetContent(shouldUpdateMobileNetwork))
+        }
+    }
+
+    private fun getInternetContent(shouldUpdateMobileNetwork: Boolean): InternetContent {
+        return InternetContent(
+            shouldUpdateMobileNetwork = shouldUpdateMobileNetwork,
+            internetDialogTitleString = getDialogTitleText(),
+            internetDialogSubTitle = getSubtitleText(),
+            activeNetworkIsCellular =
+                if (shouldUpdateMobileNetwork)
+                    internetDetailsContentController.activeNetworkIsCellular()
+                else false,
+            isCarrierNetworkActive =
+                if (shouldUpdateMobileNetwork)
+                    internetDetailsContentController.isCarrierNetworkActive()
+                else false,
+            isAirplaneModeEnabled = internetDetailsContentController.isAirplaneModeEnabled,
+            hasEthernet = internetDetailsContentController.hasEthernet(),
+            isWifiEnabled = internetDetailsContentController.isWifiEnabled,
+            hasActiveSubIdOnDds = internetDetailsContentController.hasActiveSubIdOnDds(),
+            isDeviceLocked = internetDetailsContentController.isDeviceLocked,
+            isWifiScanEnabled = internetDetailsContentController.isWifiScanEnabled(),
+            activeAutoSwitchNonDdsSubId =
+                internetDetailsContentController.getActiveAutoSwitchNonDdsSubId(),
+        )
+    }
+
+    /**
+     * Handles window focus changes. If the activity loses focus and the system UI dialog is
+     * showing, it dismisses the current alert dialog to prevent it from persisting in the
+     * background.
+     *
+     * @param dialog The internet system UI dialog whose focus state has changed.
+     * @param hasFocus True if the window has gained focus, false otherwise.
+     */
+    fun onWindowFocusChanged(dialog: SystemUIDialog, hasFocus: Boolean) {
+        if (alertDialog != null && !alertDialog!!.isShowing) {
+            if (!hasFocus && dialog.isShowing) {
+                dialog.dismiss()
+            }
+        }
+    }
+
+    private fun getDefaultCarrierName(): String? {
+        return context.getString(R.string.mobile_data_disable_message_default_carrier)
+    }
+
+    @VisibleForTesting
+    internal val internetDetailsCallback =
+        object : InternetDetailsContentController.InternetDialogCallback {
+            override fun onRefreshCarrierInfo() {
+                updateContent(shouldUpdateMobileNetwork = true)
+            }
+
+            override fun onSimStateChanged() {
+                updateContent(shouldUpdateMobileNetwork = true)
+            }
+
+            @WorkerThread
+            override fun onCapabilitiesChanged(
+                network: Network?,
+                networkCapabilities: NetworkCapabilities?,
+            ) {
+                updateContent(shouldUpdateMobileNetwork = true)
+            }
+
+            @WorkerThread
+            override fun onLost(network: Network) {
+                updateContent(shouldUpdateMobileNetwork = true)
+            }
+
+            override fun onSubscriptionsChanged(dataSubId: Int) {
+                defaultDataSubId = dataSubId
+                updateContent(shouldUpdateMobileNetwork = true)
+            }
+
+            override fun onServiceStateChanged(serviceState: ServiceState?) {
+                updateContent(shouldUpdateMobileNetwork = true)
+            }
+
+            @WorkerThread
+            override fun onDataConnectionStateChanged(state: Int, networkType: Int) {
+                updateContent(shouldUpdateMobileNetwork = true)
+            }
+
+            override fun onSignalStrengthsChanged(signalStrength: SignalStrength?) {
+                updateContent(shouldUpdateMobileNetwork = true)
+            }
+
+            override fun onUserMobileDataStateChanged(enabled: Boolean) {
+                updateContent(shouldUpdateMobileNetwork = true)
+            }
+
+            override fun onDisplayInfoChanged(telephonyDisplayInfo: TelephonyDisplayInfo?) {
+                updateContent(shouldUpdateMobileNetwork = true)
+            }
+
+            override fun onCarrierNetworkChange(active: Boolean) {
+                updateContent(shouldUpdateMobileNetwork = true)
+            }
+
+            override fun dismissDialog() {
+                if (DEBUG) {
+                    Log.d(TAG, "dismissDialog")
+                }
+                if (internetDialog != null) {
+                    internetDialog!!.dismiss()
+                    internetDialog = null
+                }
+            }
+
+            override fun onAccessPointsChanged(
+                wifiEntries: MutableList<WifiEntry>?,
+                connectedEntry: WifiEntry?,
+                ifHasMoreWifiEntries: Boolean,
+            ) {
+                // Should update the carrier network layout when it is connected under airplane
+                // mode ON.
+                val shouldUpdateCarrierNetwork =
+                    (mobileNetworkLayout.visibility == View.VISIBLE) &&
+                        internetDetailsContentController.isAirplaneModeEnabled
+                handler.post {
+                    connectedWifiEntry = connectedEntry
+                    wifiEntriesCount = wifiEntries?.size ?: 0
+                    hasMoreWifiEntries = ifHasMoreWifiEntries
+                    updateContent(shouldUpdateCarrierNetwork)
+                    adapter.setWifiEntries(wifiEntries, wifiEntriesCount)
+                    adapter.notifyDataSetChanged()
+                }
+            }
+
+            override fun onWifiScan(isScan: Boolean) {
+                setProgressBarVisible(isScan)
+            }
+        }
+
+    enum class InternetDetailsEvent(private val id: Int) : UiEventLogger.UiEventEnum {
+        @UiEvent(doc = "The Internet details became visible on the screen.")
+        INTERNET_DETAILS_VISIBLE(2071),
+        @UiEvent(doc = "The share wifi button is clicked.") SHARE_WIFI_QS_BUTTON_CLICKED(1462);
+
+        override fun getId(): Int {
+            return id
+        }
+    }
+
+    @VisibleForTesting
+    data class InternetContent(
+        val internetDialogTitleString: CharSequence,
+        val internetDialogSubTitle: CharSequence,
+        val isAirplaneModeEnabled: Boolean = false,
+        val hasEthernet: Boolean = false,
+        val shouldUpdateMobileNetwork: Boolean = false,
+        val activeNetworkIsCellular: Boolean = false,
+        val isCarrierNetworkActive: Boolean = false,
+        val isWifiEnabled: Boolean = false,
+        val hasActiveSubIdOnDds: Boolean = false,
+        val isDeviceLocked: Boolean = false,
+        val isWifiScanEnabled: Boolean = false,
+        val activeAutoSwitchNonDdsSubId: Int = SubscriptionManager.INVALID_SUBSCRIPTION_ID,
+    )
+
+    companion object {
+        private const val TAG = "InternetDetailsContent"
+        private val DEBUG: Boolean = Log.isLoggable(TAG, Log.DEBUG)
+        private const val MAX_NETWORK_COUNT = 4
+        const val CAN_CONFIG_MOBILE_DATA = "can_config_mobile_data"
+        const val CAN_CONFIG_WIFI = "can_config_wifi"
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/InternetDetailedViewModel.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/InternetDetailsViewModel.kt
similarity index 100%
rename from packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/InternetDetailedViewModel.kt
rename to packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/InternetDetailsViewModel.kt
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/InternetDialogDelegateLegacy.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/InternetDialogDelegateLegacy.java
index 82367eb..401f1a4 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/InternetDialogDelegateLegacy.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/InternetDialogDelegateLegacy.java
@@ -70,6 +70,7 @@
 import com.android.systemui.animation.DialogTransitionAnimator;
 import com.android.systemui.dagger.qualifiers.Background;
 import com.android.systemui.dagger.qualifiers.Main;
+import com.android.systemui.qs.flags.QsDetailedView;
 import com.android.systemui.res.R;
 import com.android.systemui.shade.ShadeDisplayAware;
 import com.android.systemui.shade.domain.interactor.ShadeDialogContextInteractor;
@@ -207,7 +208,8 @@
             KeyguardStateController keyguardStateController,
             SystemUIDialog.Factory systemUIDialogFactory,
             ShadeDialogContextInteractor shadeDialogContextInteractor) {
-        // TODO: b/377388104 QsDetailedView.assertInLegacyMode();
+        // If `QsDetailedView` is enabled, it should show the details view.
+        QsDetailedView.assertInLegacyMode();
 
         mAboveStatusBar = aboveStatusBar;
         mSystemUIDialogFactory = systemUIDialogFactory;
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/InternetDialogManager.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/InternetDialogManager.kt
index 8a54648..5f82e60 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/InternetDialogManager.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/InternetDialogManager.kt
@@ -23,6 +23,7 @@
 import com.android.systemui.coroutines.newTracingContext
 import com.android.systemui.dagger.SysUISingleton
 import com.android.systemui.dagger.qualifiers.Background
+import com.android.systemui.qs.flags.QsDetailedView
 import com.android.systemui.statusbar.phone.SystemUIDialog
 import javax.inject.Inject
 import kotlinx.coroutines.CoroutineDispatcher
@@ -42,21 +43,24 @@
     @Background private val bgDispatcher: CoroutineDispatcher,
 ) {
     private lateinit var coroutineScope: CoroutineScope
+
     companion object {
         private const val INTERACTION_JANK_TAG = "internet"
         var dialog: SystemUIDialog? = null
     }
 
     /**
-     * Creates a [InternetDialogDelegateLegacy]. The dialog will be animated from [expandable] if
-     * it is not null.
+     * Creates a [InternetDialogDelegateLegacy]. The dialog will be animated from [expandable] if it
+     * is not null.
      */
     fun create(
         aboveStatusBar: Boolean,
         canConfigMobileData: Boolean,
         canConfigWifi: Boolean,
-        expandable: Expandable?
+        expandable: Expandable?,
     ) {
+        // If `QsDetailedView` is enabled, it should show the details view.
+        QsDetailedView.assertInLegacyMode()
         if (dialog != null) {
             if (DEBUG) {
                 Log.d(TAG, "InternetDialog is showing, do not create it twice.")
@@ -64,11 +68,11 @@
             return
         } else {
             coroutineScope = CoroutineScope(bgDispatcher + newTracingContext("InternetDialogScope"))
-            // TODO: b/377388104 check the QsDetailedView flag to use the correct dialogFactory
             dialog =
                 dialogFactory
                     .create(aboveStatusBar, canConfigMobileData, canConfigWifi, coroutineScope)
                     .createDialog()
+
             val controller =
                 expandable?.dialogTransitionController(
                     DialogCuj(InteractionJankMonitor.CUJ_SHADE_DIALOG_OPEN, INTERACTION_JANK_TAG)
@@ -77,10 +81,9 @@
                 dialogTransitionAnimator.show(
                     dialog!!,
                     controller,
-                    animateBackgroundBoundsChange = true
+                    animateBackgroundBoundsChange = true,
                 )
-            }
-                ?: dialog?.show()
+            } ?: dialog?.show()
         }
     }
 
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/dialog/InternetDetailsContentManagerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/dialog/InternetDetailsContentManagerTest.kt
new file mode 100644
index 0000000..a192446
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/dialog/InternetDetailsContentManagerTest.kt
@@ -0,0 +1,819 @@
+/*
+ * 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.systemui.qs.tiles.dialog
+
+import android.content.Intent
+import android.os.Handler
+import android.os.fakeExecutorHandler
+import android.telephony.SubscriptionManager
+import android.telephony.TelephonyManager
+import android.telephony.telephonyManager
+import android.testing.TestableLooper.RunWithLooper
+import android.view.LayoutInflater
+import android.view.View
+import android.widget.Button
+import android.widget.LinearLayout
+import android.widget.Switch
+import android.widget.TextView
+import androidx.recyclerview.widget.RecyclerView
+import androidx.test.annotation.UiThreadTest
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.SmallTest
+import com.android.dx.mockito.inline.extended.ExtendedMockito
+import com.android.internal.logging.UiEventLogger
+import com.android.settingslib.wifi.WifiEnterpriseRestrictionUtils
+import com.android.systemui.Flags
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.animation.DialogTransitionAnimator
+import com.android.systemui.flags.setFlagValue
+import com.android.systemui.kosmos.Kosmos
+import com.android.systemui.res.R
+import com.android.systemui.statusbar.policy.KeyguardStateController
+import com.android.systemui.util.concurrency.FakeExecutor
+import com.android.systemui.util.time.FakeSystemClock
+import com.android.wifitrackerlib.WifiEntry
+import com.google.common.truth.Truth.assertThat
+import kotlinx.coroutines.CoroutineScope
+import org.junit.After
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.mockito.ArgumentMatchers
+import org.mockito.MockitoSession
+import org.mockito.kotlin.clearInvocations
+import org.mockito.kotlin.mock
+import org.mockito.kotlin.verify
+import org.mockito.kotlin.whenever
+
+@SmallTest
+@RunWith(AndroidJUnit4::class)
+@RunWithLooper(setAsMainLooper = true)
+@UiThreadTest
+class InternetDetailsContentManagerTest : SysuiTestCase() {
+    private val kosmos = Kosmos()
+    private val handler: Handler = kosmos.fakeExecutorHandler
+    private val scope: CoroutineScope = mock<CoroutineScope>()
+    private val telephonyManager: TelephonyManager = kosmos.telephonyManager
+    private val internetWifiEntry: WifiEntry = mock<WifiEntry>()
+    private val wifiEntries: List<WifiEntry> = mock<List<WifiEntry>>()
+    private val internetAdapter = mock<InternetAdapter>()
+    private val internetDetailsContentController: InternetDetailsContentController =
+        mock<InternetDetailsContentController>()
+    private val keyguard: KeyguardStateController = mock<KeyguardStateController>()
+    private val dialogTransitionAnimator: DialogTransitionAnimator =
+        mock<DialogTransitionAnimator>()
+    private val bgExecutor = FakeExecutor(FakeSystemClock())
+    private lateinit var internetDetailsContentManager: InternetDetailsContentManager
+    private var subTitle: View? = null
+    private var ethernet: LinearLayout? = null
+    private var mobileDataLayout: LinearLayout? = null
+    private var mobileToggleSwitch: Switch? = null
+    private var wifiToggle: LinearLayout? = null
+    private var wifiToggleSwitch: Switch? = null
+    private var wifiToggleSummary: TextView? = null
+    private var connectedWifi: LinearLayout? = null
+    private var wifiList: RecyclerView? = null
+    private var seeAll: LinearLayout? = null
+    private var wifiScanNotify: LinearLayout? = null
+    private var airplaneModeSummaryText: TextView? = null
+    private var mockitoSession: MockitoSession? = null
+    private var sharedWifiButton: Button? = null
+    private lateinit var contentView: View
+
+    @Before
+    fun setUp() {
+        // TODO: b/377388104 enable this flag after integrating with details view.
+        mSetFlagsRule.setFlagValue(Flags.FLAG_QS_TILE_DETAILED_VIEW, false)
+        whenever(telephonyManager.createForSubscriptionId(ArgumentMatchers.anyInt()))
+            .thenReturn(telephonyManager)
+        whenever(internetWifiEntry.title).thenReturn(WIFI_TITLE)
+        whenever(internetWifiEntry.getSummary(false)).thenReturn(WIFI_SUMMARY)
+        whenever(internetWifiEntry.isDefaultNetwork).thenReturn(true)
+        whenever(internetWifiEntry.hasInternetAccess()).thenReturn(true)
+        whenever(wifiEntries.size).thenReturn(1)
+        whenever(internetDetailsContentController.getDialogTitleText()).thenReturn(TITLE)
+        whenever(internetDetailsContentController.getMobileNetworkTitle(ArgumentMatchers.anyInt()))
+            .thenReturn(MOBILE_NETWORK_TITLE)
+        whenever(
+                internetDetailsContentController.getMobileNetworkSummary(ArgumentMatchers.anyInt())
+            )
+            .thenReturn(MOBILE_NETWORK_SUMMARY)
+        whenever(internetDetailsContentController.isWifiEnabled).thenReturn(true)
+        whenever(internetDetailsContentController.activeAutoSwitchNonDdsSubId)
+            .thenReturn(SubscriptionManager.INVALID_SUBSCRIPTION_ID)
+        mockitoSession =
+            ExtendedMockito.mockitoSession()
+                .spyStatic(WifiEnterpriseRestrictionUtils::class.java)
+                .startMocking()
+        whenever(WifiEnterpriseRestrictionUtils.isChangeWifiStateAllowed(mContext)).thenReturn(true)
+        createView()
+    }
+
+    private fun createView() {
+        contentView =
+            LayoutInflater.from(mContext).inflate(R.layout.internet_connectivity_dialog, null)
+        internetDetailsContentManager =
+            InternetDetailsContentManager(
+                internetDetailsContentController,
+                canConfigMobileData = true,
+                canConfigWifi = true,
+                coroutineScope = scope,
+                context = mContext,
+                internetDialog = null,
+                uiEventLogger = mock<UiEventLogger>(),
+                dialogTransitionAnimator = dialogTransitionAnimator,
+                handler = handler,
+                backgroundExecutor = bgExecutor,
+                keyguard = keyguard,
+            )
+
+        internetDetailsContentManager.bind(contentView)
+        internetDetailsContentManager.adapter = internetAdapter
+        internetDetailsContentManager.connectedWifiEntry = internetWifiEntry
+        internetDetailsContentManager.wifiEntriesCount = wifiEntries.size
+
+        subTitle = contentView.requireViewById(R.id.internet_dialog_subtitle)
+        ethernet = contentView.requireViewById(R.id.ethernet_layout)
+        mobileDataLayout = contentView.requireViewById(R.id.mobile_network_layout)
+        mobileToggleSwitch = contentView.requireViewById(R.id.mobile_toggle)
+        wifiToggle = contentView.requireViewById(R.id.turn_on_wifi_layout)
+        wifiToggleSwitch = contentView.requireViewById(R.id.wifi_toggle)
+        wifiToggleSummary = contentView.requireViewById(R.id.wifi_toggle_summary)
+        connectedWifi = contentView.requireViewById(R.id.wifi_connected_layout)
+        wifiList = contentView.requireViewById(R.id.wifi_list_layout)
+        seeAll = contentView.requireViewById(R.id.see_all_layout)
+        wifiScanNotify = contentView.requireViewById(R.id.wifi_scan_notify_layout)
+        airplaneModeSummaryText = contentView.requireViewById(R.id.airplane_mode_summary)
+        sharedWifiButton = contentView.requireViewById(R.id.share_wifi_button)
+    }
+
+    @After
+    fun tearDown() {
+        internetDetailsContentManager.unBind()
+        mockitoSession!!.finishMocking()
+    }
+
+    @Test
+    fun createView_setAccessibilityPaneTitleToQuickSettings() {
+        assertThat(contentView.accessibilityPaneTitle)
+            .isEqualTo(mContext.getText(R.string.accessibility_desc_quick_settings))
+    }
+
+    @Test
+    fun hideWifiViews_WifiViewsGone() {
+        internetDetailsContentManager.hideWifiViews()
+
+        assertThat(internetDetailsContentManager.isProgressBarVisible).isFalse()
+        assertThat(wifiToggle!!.visibility).isEqualTo(View.GONE)
+        assertThat(connectedWifi!!.visibility).isEqualTo(View.GONE)
+        assertThat(wifiList!!.visibility).isEqualTo(View.GONE)
+        assertThat(seeAll!!.visibility).isEqualTo(View.GONE)
+    }
+
+    @Test
+    fun updateContent_withApmOn_internetDialogSubTitleGone() {
+        whenever(internetDetailsContentController.isAirplaneModeEnabled).thenReturn(true)
+        internetDetailsContentManager.updateContent(true)
+        bgExecutor.runAllReady()
+
+        internetDetailsContentManager.internetContentData.observe(
+            internetDetailsContentManager.lifecycleOwner!!
+        ) {
+            assertThat(subTitle!!.visibility).isEqualTo(View.VISIBLE)
+        }
+    }
+
+    @Test
+    fun updateContent_withApmOff_internetDialogSubTitleVisible() {
+        whenever(internetDetailsContentController.isAirplaneModeEnabled).thenReturn(false)
+        internetDetailsContentManager.updateContent(true)
+        bgExecutor.runAllReady()
+
+        internetDetailsContentManager.internetContentData.observe(
+            internetDetailsContentManager.lifecycleOwner!!
+        ) {
+            assertThat(subTitle!!.visibility).isEqualTo(View.VISIBLE)
+        }
+    }
+
+    @Test
+    fun updateContent_apmOffAndHasEthernet_showEthernet() {
+        whenever(internetDetailsContentController.isAirplaneModeEnabled).thenReturn(false)
+        whenever(internetDetailsContentController.hasEthernet()).thenReturn(true)
+        internetDetailsContentManager.updateContent(true)
+        bgExecutor.runAllReady()
+
+        internetDetailsContentManager.internetContentData.observe(
+            internetDetailsContentManager.lifecycleOwner!!
+        ) {
+            assertThat(ethernet!!.visibility).isEqualTo(View.VISIBLE)
+        }
+    }
+
+    @Test
+    fun updateContent_apmOffAndNoEthernet_hideEthernet() {
+        whenever(internetDetailsContentController.isAirplaneModeEnabled).thenReturn(false)
+        whenever(internetDetailsContentController.hasEthernet()).thenReturn(false)
+        internetDetailsContentManager.updateContent(true)
+        bgExecutor.runAllReady()
+
+        internetDetailsContentManager.internetContentData.observe(
+            internetDetailsContentManager.lifecycleOwner!!
+        ) {
+            assertThat(ethernet!!.visibility).isEqualTo(View.GONE)
+        }
+    }
+
+    @Test
+    fun updateContent_apmOnAndHasEthernet_showEthernet() {
+        whenever(internetDetailsContentController.isAirplaneModeEnabled).thenReturn(true)
+        whenever(internetDetailsContentController.hasEthernet()).thenReturn(true)
+        internetDetailsContentManager.updateContent(true)
+        bgExecutor.runAllReady()
+
+        internetDetailsContentManager.internetContentData.observe(
+            internetDetailsContentManager.lifecycleOwner!!
+        ) {
+            assertThat(ethernet!!.visibility).isEqualTo(View.VISIBLE)
+        }
+    }
+
+    @Test
+    fun updateContent_apmOnAndNoEthernet_hideEthernet() {
+        whenever(internetDetailsContentController.isAirplaneModeEnabled).thenReturn(true)
+        whenever(internetDetailsContentController.hasEthernet()).thenReturn(false)
+        internetDetailsContentManager.updateContent(true)
+        bgExecutor.runAllReady()
+
+        internetDetailsContentManager.internetContentData.observe(
+            internetDetailsContentManager.lifecycleOwner!!
+        ) {
+            assertThat(ethernet!!.visibility).isEqualTo(View.GONE)
+        }
+    }
+
+    @Test
+    fun updateContent_apmOffAndNotCarrierNetwork_mobileDataLayoutGone() {
+        // Mobile network should be gone if the list of active subscriptionId is null.
+        whenever(internetDetailsContentController.isCarrierNetworkActive).thenReturn(false)
+        whenever(internetDetailsContentController.isAirplaneModeEnabled).thenReturn(false)
+        whenever(internetDetailsContentController.hasActiveSubIdOnDds()).thenReturn(false)
+        internetDetailsContentManager.updateContent(true)
+        bgExecutor.runAllReady()
+
+        internetDetailsContentManager.internetContentData.observe(
+            internetDetailsContentManager.lifecycleOwner!!
+        ) {
+            assertThat(mobileDataLayout!!.visibility).isEqualTo(View.GONE)
+        }
+    }
+
+    @Test
+    fun updateContent_apmOnWithCarrierNetworkAndWifiStatus_mobileDataLayoutVisible() {
+        // Carrier network should be visible if airplane mode ON and Wi-Fi is ON.
+        whenever(internetDetailsContentController.isCarrierNetworkActive).thenReturn(true)
+        whenever(internetDetailsContentController.isAirplaneModeEnabled).thenReturn(true)
+        whenever(internetDetailsContentController.isWifiEnabled).thenReturn(true)
+        internetDetailsContentManager.updateContent(true)
+        bgExecutor.runAllReady()
+
+        internetDetailsContentManager.internetContentData.observe(
+            internetDetailsContentManager.lifecycleOwner!!
+        ) {
+            assertThat(mobileDataLayout!!.visibility).isEqualTo(View.VISIBLE)
+        }
+    }
+
+    @Test
+    fun updateContent_apmOnWithCarrierNetworkAndWifiStatus_mobileDataLayoutGone() {
+        // Carrier network should be gone if airplane mode ON and Wi-Fi is off.
+        whenever(internetDetailsContentController.isCarrierNetworkActive).thenReturn(true)
+        whenever(internetDetailsContentController.isAirplaneModeEnabled).thenReturn(true)
+        whenever(internetDetailsContentController.isWifiEnabled).thenReturn(false)
+        internetDetailsContentManager.updateContent(true)
+        bgExecutor.runAllReady()
+
+        internetDetailsContentManager.internetContentData.observe(
+            internetDetailsContentManager.lifecycleOwner!!
+        ) {
+            assertThat(mobileDataLayout!!.visibility).isEqualTo(View.GONE)
+        }
+    }
+
+    @Test
+    fun updateContent_apmOnAndNoCarrierNetwork_mobileDataLayoutGone() {
+        whenever(internetDetailsContentController.isCarrierNetworkActive).thenReturn(false)
+        whenever(internetDetailsContentController.isAirplaneModeEnabled).thenReturn(true)
+        internetDetailsContentManager.updateContent(true)
+        bgExecutor.runAllReady()
+
+        internetDetailsContentManager.internetContentData.observe(
+            internetDetailsContentManager.lifecycleOwner!!
+        ) {
+            assertThat(mobileDataLayout!!.visibility).isEqualTo(View.GONE)
+        }
+    }
+
+    @Test
+    fun updateContent_apmOnAndWifiOnHasCarrierNetwork_showAirplaneSummary() {
+        whenever(internetDetailsContentController.isCarrierNetworkActive).thenReturn(true)
+        whenever(internetDetailsContentController.isAirplaneModeEnabled).thenReturn(true)
+        internetDetailsContentManager.connectedWifiEntry = null
+        whenever(internetDetailsContentController.activeNetworkIsCellular()).thenReturn(false)
+        internetDetailsContentManager.updateContent(true)
+        bgExecutor.runAllReady()
+
+        internetDetailsContentManager.internetContentData.observe(
+            internetDetailsContentManager.lifecycleOwner!!
+        ) {
+            assertThat(mobileDataLayout!!.visibility).isEqualTo(View.VISIBLE)
+            assertThat(airplaneModeSummaryText!!.visibility).isEqualTo(View.VISIBLE)
+        }
+    }
+
+    @Test
+    fun updateContent_apmOffAndWifiOnHasCarrierNetwork_notShowApmSummary() {
+        whenever(internetDetailsContentController.isCarrierNetworkActive).thenReturn(true)
+        whenever(internetDetailsContentController.isAirplaneModeEnabled).thenReturn(false)
+        internetDetailsContentManager.connectedWifiEntry = null
+        whenever(internetDetailsContentController.activeNetworkIsCellular()).thenReturn(false)
+        internetDetailsContentManager.updateContent(true)
+        bgExecutor.runAllReady()
+
+        internetDetailsContentManager.internetContentData.observe(
+            internetDetailsContentManager.lifecycleOwner!!
+        ) {
+            assertThat(airplaneModeSummaryText!!.visibility).isEqualTo(View.GONE)
+        }
+    }
+
+    @Test
+    fun updateContent_apmOffAndHasCarrierNetwork_notShowApmSummary() {
+        whenever(internetDetailsContentController.isCarrierNetworkActive).thenReturn(true)
+        whenever(internetDetailsContentController.isAirplaneModeEnabled).thenReturn(false)
+        internetDetailsContentManager.updateContent(true)
+        bgExecutor.runAllReady()
+
+        internetDetailsContentManager.internetContentData.observe(
+            internetDetailsContentManager.lifecycleOwner!!
+        ) {
+            assertThat(airplaneModeSummaryText!!.visibility).isEqualTo(View.GONE)
+        }
+    }
+
+    @Test
+    fun updateContent_apmOnAndNoCarrierNetwork_notShowApmSummary() {
+        whenever(internetDetailsContentController.isCarrierNetworkActive).thenReturn(false)
+        whenever(internetDetailsContentController.isAirplaneModeEnabled).thenReturn(true)
+        internetDetailsContentManager.updateContent(true)
+        bgExecutor.runAllReady()
+
+        internetDetailsContentManager.internetContentData.observe(
+            internetDetailsContentManager.lifecycleOwner!!
+        ) {
+            assertThat(airplaneModeSummaryText!!.visibility).isEqualTo(View.GONE)
+        }
+    }
+
+    @Test
+    fun updateContent_mobileDataIsEnabled_checkMobileDataSwitch() {
+        whenever(internetDetailsContentController.hasActiveSubIdOnDds()).thenReturn(true)
+        whenever(internetDetailsContentController.isCarrierNetworkActive).thenReturn(true)
+        whenever(internetDetailsContentController.isMobileDataEnabled).thenReturn(true)
+        mobileToggleSwitch!!.isChecked = false
+        internetDetailsContentManager.updateContent(true)
+        bgExecutor.runAllReady()
+
+        internetDetailsContentManager.internetContentData.observe(
+            internetDetailsContentManager.lifecycleOwner!!
+        ) {
+            assertThat(mobileToggleSwitch!!.isChecked).isTrue()
+        }
+    }
+
+    @Test
+    fun updateContent_mobileDataIsNotChanged_checkMobileDataSwitch() {
+        whenever(internetDetailsContentController.hasActiveSubIdOnDds()).thenReturn(true)
+        whenever(internetDetailsContentController.isCarrierNetworkActive).thenReturn(true)
+        whenever(internetDetailsContentController.isMobileDataEnabled).thenReturn(false)
+        mobileToggleSwitch!!.isChecked = false
+        internetDetailsContentManager.updateContent(true)
+        bgExecutor.runAllReady()
+
+        internetDetailsContentManager.internetContentData.observe(
+            internetDetailsContentManager.lifecycleOwner!!
+        ) {
+            assertThat(mobileToggleSwitch!!.isChecked).isFalse()
+        }
+    }
+
+    @Test
+    fun updateContent_wifiOnAndHasInternetWifi_showConnectedWifi() {
+        whenever(internetDetailsContentController.activeAutoSwitchNonDdsSubId).thenReturn(1)
+        whenever(internetDetailsContentController.hasActiveSubIdOnDds()).thenReturn(true)
+
+        // The preconditions WiFi ON and Internet WiFi are already in setUp()
+        whenever(internetDetailsContentController.activeNetworkIsCellular()).thenReturn(false)
+
+        internetDetailsContentManager.updateContent(true)
+        bgExecutor.runAllReady()
+
+        internetDetailsContentManager.internetContentData.observe(
+            internetDetailsContentManager.lifecycleOwner!!
+        ) {
+            assertThat(connectedWifi!!.visibility).isEqualTo(View.VISIBLE)
+            val secondaryLayout =
+                contentView.requireViewById<LinearLayout>(R.id.secondary_mobile_network_layout)
+            assertThat(secondaryLayout.visibility).isEqualTo(View.GONE)
+        }
+    }
+
+    @Test
+    fun updateContent_wifiOnAndNoConnectedWifi_hideConnectedWifi() {
+        // The precondition WiFi ON is already in setUp()
+        internetDetailsContentManager.connectedWifiEntry = null
+        whenever(internetDetailsContentController.activeNetworkIsCellular()).thenReturn(false)
+
+        internetDetailsContentManager.updateContent(false)
+        bgExecutor.runAllReady()
+
+        internetDetailsContentManager.internetContentData.observe(
+            internetDetailsContentManager.lifecycleOwner!!
+        ) {
+            assertThat(connectedWifi!!.visibility).isEqualTo(View.GONE)
+        }
+    }
+
+    @Test
+    fun updateContent_wifiOnAndNoWifiEntry_showWifiListAndSeeAllArea() {
+        // The precondition WiFi ON is already in setUp()
+        internetDetailsContentManager.connectedWifiEntry = null
+        internetDetailsContentManager.wifiEntriesCount = 0
+        internetDetailsContentManager.updateContent(false)
+        bgExecutor.runAllReady()
+
+        internetDetailsContentManager.internetContentData.observe(
+            internetDetailsContentManager.lifecycleOwner!!
+        ) {
+            assertThat(connectedWifi!!.visibility).isEqualTo(View.GONE)
+            // Show a blank block to fix the details content height even if there is no WiFi list
+            assertThat(wifiList!!.visibility).isEqualTo(View.VISIBLE)
+            verify(internetAdapter).setMaxEntriesCount(3)
+            assertThat(seeAll!!.visibility).isEqualTo(View.INVISIBLE)
+        }
+    }
+
+    @Test
+    fun updateContent_wifiOnAndOneWifiEntry_showWifiListAndSeeAllArea() {
+        // The precondition WiFi ON is already in setUp()
+        internetDetailsContentManager.connectedWifiEntry = null
+        internetDetailsContentManager.wifiEntriesCount = 1
+        internetDetailsContentManager.updateContent(false)
+        bgExecutor.runAllReady()
+
+        internetDetailsContentManager.internetContentData.observe(
+            internetDetailsContentManager.lifecycleOwner!!
+        ) {
+            assertThat(connectedWifi!!.visibility).isEqualTo(View.GONE)
+            // Show a blank block to fix the details content height even if there is no WiFi list
+            assertThat(wifiList!!.visibility).isEqualTo(View.VISIBLE)
+            verify(internetAdapter).setMaxEntriesCount(3)
+            assertThat(seeAll!!.visibility).isEqualTo(View.INVISIBLE)
+        }
+    }
+
+    @Test
+    fun updateContent_wifiOnAndHasConnectedWifi_showAllWifiAndSeeAllArea() {
+        // The preconditions WiFi ON and WiFi entries are already in setUp()
+        internetDetailsContentManager.wifiEntriesCount = 0
+        internetDetailsContentManager.updateContent(false)
+        bgExecutor.runAllReady()
+
+        internetDetailsContentManager.internetContentData.observe(
+            internetDetailsContentManager.lifecycleOwner!!
+        ) {
+            assertThat(connectedWifi!!.visibility).isEqualTo(View.VISIBLE)
+            // Show a blank block to fix the details content height even if there is no WiFi list
+            assertThat(wifiList!!.visibility).isEqualTo(View.VISIBLE)
+            verify(internetAdapter).setMaxEntriesCount(2)
+            assertThat(seeAll!!.visibility).isEqualTo(View.INVISIBLE)
+        }
+    }
+
+    @Test
+    fun updateContent_wifiOnAndHasMaxWifiList_showWifiListAndSeeAll() {
+        // The preconditions WiFi ON and WiFi entries are already in setUp()
+        internetDetailsContentManager.connectedWifiEntry = null
+        internetDetailsContentManager.wifiEntriesCount =
+            InternetDetailsContentController.MAX_WIFI_ENTRY_COUNT
+        internetDetailsContentManager.hasMoreWifiEntries = true
+        internetDetailsContentManager.updateContent(false)
+        bgExecutor.runAllReady()
+
+        internetDetailsContentManager.internetContentData.observe(
+            internetDetailsContentManager.lifecycleOwner!!
+        ) {
+            assertThat(connectedWifi!!.visibility).isEqualTo(View.GONE)
+            assertThat(wifiList!!.visibility).isEqualTo(View.VISIBLE)
+            verify(internetAdapter).setMaxEntriesCount(3)
+            assertThat(seeAll!!.visibility).isEqualTo(View.VISIBLE)
+        }
+    }
+
+    @Test
+    fun updateContent_wifiOnAndHasBothWifiEntry_showBothWifiEntryAndSeeAll() {
+        // The preconditions WiFi ON and WiFi entries are already in setUp()
+        internetDetailsContentManager.wifiEntriesCount =
+            InternetDetailsContentController.MAX_WIFI_ENTRY_COUNT - 1
+        internetDetailsContentManager.hasMoreWifiEntries = true
+        internetDetailsContentManager.updateContent(false)
+        bgExecutor.runAllReady()
+
+        internetDetailsContentManager.internetContentData.observe(
+            internetDetailsContentManager.lifecycleOwner!!
+        ) {
+            assertThat(connectedWifi!!.visibility).isEqualTo(View.VISIBLE)
+            assertThat(wifiList!!.visibility).isEqualTo(View.VISIBLE)
+            verify(internetAdapter).setMaxEntriesCount(2)
+            assertThat(seeAll!!.visibility).isEqualTo(View.VISIBLE)
+        }
+    }
+
+    @Test
+    fun updateContent_deviceLockedAndNoConnectedWifi_showWifiToggle() {
+        // The preconditions WiFi entries are already in setUp()
+        whenever(internetDetailsContentController.isDeviceLocked).thenReturn(true)
+        internetDetailsContentManager.connectedWifiEntry = null
+        internetDetailsContentManager.updateContent(false)
+        bgExecutor.runAllReady()
+
+        internetDetailsContentManager.internetContentData.observe(
+            internetDetailsContentManager.lifecycleOwner!!
+        ) {
+            // Show WiFi Toggle without background
+            assertThat(wifiToggle!!.visibility).isEqualTo(View.VISIBLE)
+            assertThat(wifiToggle!!.background).isNull()
+            // Hide Wi-Fi networks and See all
+            assertThat(connectedWifi!!.visibility).isEqualTo(View.GONE)
+            assertThat(wifiList!!.visibility).isEqualTo(View.GONE)
+            assertThat(seeAll!!.visibility).isEqualTo(View.GONE)
+        }
+    }
+
+    @Test
+    fun updateContent_deviceLockedAndHasConnectedWifi_showWifiToggleWithBackground() {
+        // The preconditions WiFi ON and WiFi entries are already in setUp()
+        whenever(internetDetailsContentController.isDeviceLocked).thenReturn(true)
+        internetDetailsContentManager.updateContent(false)
+        bgExecutor.runAllReady()
+
+        internetDetailsContentManager.internetContentData.observe(
+            internetDetailsContentManager.lifecycleOwner!!
+        ) {
+            // Show WiFi Toggle with highlight background
+            assertThat(wifiToggle!!.visibility).isEqualTo(View.VISIBLE)
+            assertThat(wifiToggle!!.background).isNotNull()
+            // Hide Wi-Fi networks and See all
+            assertThat(connectedWifi!!.visibility).isEqualTo(View.GONE)
+            assertThat(wifiList!!.visibility).isEqualTo(View.GONE)
+            assertThat(seeAll!!.visibility).isEqualTo(View.GONE)
+        }
+    }
+
+    @Test
+    fun updateContent_disallowChangeWifiState_disableWifiSwitch() {
+        whenever(WifiEnterpriseRestrictionUtils.isChangeWifiStateAllowed(mContext))
+            .thenReturn(false)
+        createView()
+        internetDetailsContentManager.updateContent(false)
+        bgExecutor.runAllReady()
+
+        internetDetailsContentManager.internetContentData.observe(
+            internetDetailsContentManager.lifecycleOwner!!
+        ) {
+            // Disable Wi-Fi switch and show restriction message in summary.
+            assertThat(wifiToggleSwitch!!.isEnabled).isFalse()
+            assertThat(wifiToggleSummary!!.visibility).isEqualTo(View.VISIBLE)
+            assertThat(wifiToggleSummary!!.text.length).isNotEqualTo(0)
+        }
+    }
+
+    @Test
+    fun updateContent_allowChangeWifiState_enableWifiSwitch() {
+        whenever(WifiEnterpriseRestrictionUtils.isChangeWifiStateAllowed(mContext)).thenReturn(true)
+        createView()
+        internetDetailsContentManager.updateContent(false)
+        bgExecutor.runAllReady()
+
+        internetDetailsContentManager.internetContentData.observe(
+            internetDetailsContentManager.lifecycleOwner!!
+        ) {
+            // Enable Wi-Fi switch and hide restriction message in summary.
+            assertThat(wifiToggleSwitch!!.isEnabled).isTrue()
+            assertThat(wifiToggleSummary!!.visibility).isEqualTo(View.GONE)
+        }
+    }
+
+    @Test
+    fun updateContent_showSecondaryDataSub() {
+        whenever(internetDetailsContentController.activeAutoSwitchNonDdsSubId).thenReturn(1)
+        whenever(internetDetailsContentController.hasActiveSubIdOnDds()).thenReturn(true)
+        whenever(internetDetailsContentController.isAirplaneModeEnabled).thenReturn(false)
+
+        clearInvocations(internetDetailsContentController)
+        internetDetailsContentManager.updateContent(true)
+        bgExecutor.runAllReady()
+
+        internetDetailsContentManager.internetContentData.observe(
+            internetDetailsContentManager.lifecycleOwner!!
+        ) {
+            val primaryLayout =
+                contentView.requireViewById<LinearLayout>(R.id.mobile_network_layout)
+            val secondaryLayout =
+                contentView.requireViewById<LinearLayout>(R.id.secondary_mobile_network_layout)
+
+            verify(internetDetailsContentController).getMobileNetworkSummary(1)
+            assertThat(primaryLayout.background).isNotEqualTo(secondaryLayout.background)
+        }
+    }
+
+    @Test
+    fun updateContent_wifiOn_hideWifiScanNotify() {
+        // The preconditions WiFi ON and WiFi entries are already in setUp()
+        internetDetailsContentManager.updateContent(false)
+        bgExecutor.runAllReady()
+
+        internetDetailsContentManager.internetContentData.observe(
+            internetDetailsContentManager.lifecycleOwner!!
+        ) {
+            assertThat(wifiScanNotify!!.visibility).isEqualTo(View.GONE)
+        }
+
+        assertThat(wifiScanNotify!!.visibility).isEqualTo(View.GONE)
+    }
+
+    @Test
+    fun updateContent_wifiOffAndWifiScanOff_hideWifiScanNotify() {
+        whenever(internetDetailsContentController.isWifiEnabled).thenReturn(false)
+        whenever(internetDetailsContentController.isWifiScanEnabled).thenReturn(false)
+        internetDetailsContentManager.updateContent(false)
+        bgExecutor.runAllReady()
+
+        internetDetailsContentManager.internetContentData.observe(
+            internetDetailsContentManager.lifecycleOwner!!
+        ) {
+            assertThat(wifiScanNotify!!.visibility).isEqualTo(View.GONE)
+        }
+
+        assertThat(wifiScanNotify!!.visibility).isEqualTo(View.GONE)
+    }
+
+    @Test
+    fun updateContent_wifiOffAndWifiScanOnAndDeviceLocked_hideWifiScanNotify() {
+        whenever(internetDetailsContentController.isWifiEnabled).thenReturn(false)
+        whenever(internetDetailsContentController.isWifiScanEnabled).thenReturn(true)
+        whenever(internetDetailsContentController.isDeviceLocked).thenReturn(true)
+        internetDetailsContentManager.updateContent(false)
+        bgExecutor.runAllReady()
+
+        internetDetailsContentManager.internetContentData.observe(
+            internetDetailsContentManager.lifecycleOwner!!
+        ) {
+            assertThat(wifiScanNotify!!.visibility).isEqualTo(View.GONE)
+        }
+
+        assertThat(wifiScanNotify!!.visibility).isEqualTo(View.GONE)
+    }
+
+    @Test
+    fun updateContent_wifiOffAndWifiScanOnAndDeviceUnlocked_showWifiScanNotify() {
+        whenever(internetDetailsContentController.isWifiEnabled).thenReturn(false)
+        whenever(internetDetailsContentController.isWifiScanEnabled).thenReturn(true)
+        whenever(internetDetailsContentController.isDeviceLocked).thenReturn(false)
+        internetDetailsContentManager.updateContent(false)
+        bgExecutor.runAllReady()
+
+        internetDetailsContentManager.internetContentData.observe(
+            internetDetailsContentManager.lifecycleOwner!!
+        ) {
+            assertThat(wifiScanNotify!!.visibility).isEqualTo(View.VISIBLE)
+            val wifiScanNotifyText =
+                contentView.requireViewById<TextView>(R.id.wifi_scan_notify_text)
+            assertThat(wifiScanNotifyText.text.length).isNotEqualTo(0)
+            assertThat(wifiScanNotifyText.movementMethod).isNotNull()
+        }
+    }
+
+    @Test
+    fun updateContent_wifiIsDisabled_uncheckWifiSwitch() {
+        whenever(internetDetailsContentController.isWifiEnabled).thenReturn(false)
+        wifiToggleSwitch!!.isChecked = true
+        internetDetailsContentManager.updateContent(false)
+        bgExecutor.runAllReady()
+
+        internetDetailsContentManager.internetContentData.observe(
+            internetDetailsContentManager.lifecycleOwner!!
+        ) {
+            assertThat(wifiToggleSwitch!!.isChecked).isFalse()
+        }
+    }
+
+    @Test
+    @Throws(Exception::class)
+    fun updateContent_wifiIsEnabled_checkWifiSwitch() {
+        whenever(internetDetailsContentController.isWifiEnabled).thenReturn(true)
+        wifiToggleSwitch!!.isChecked = false
+        internetDetailsContentManager.updateContent(false)
+        bgExecutor.runAllReady()
+
+        internetDetailsContentManager.internetContentData.observe(
+            internetDetailsContentManager.lifecycleOwner!!
+        ) {
+            assertThat(wifiToggleSwitch!!.isChecked).isTrue()
+        }
+    }
+
+    @Test
+    fun onClickSeeMoreButton_clickSeeAll_verifyLaunchNetworkSetting() {
+        seeAll!!.performClick()
+
+        verify(internetDetailsContentController)
+            .launchNetworkSetting(contentView.requireViewById(R.id.see_all_layout))
+    }
+
+    @Test
+    fun onWifiScan_isScanTrue_setProgressBarVisibleTrue() {
+        internetDetailsContentManager.isProgressBarVisible = false
+
+        internetDetailsContentManager.internetDetailsCallback.onWifiScan(true)
+
+        assertThat(internetDetailsContentManager.isProgressBarVisible).isTrue()
+    }
+
+    @Test
+    fun onWifiScan_isScanFalse_setProgressBarVisibleFalse() {
+        internetDetailsContentManager.isProgressBarVisible = true
+
+        internetDetailsContentManager.internetDetailsCallback.onWifiScan(false)
+
+        assertThat(internetDetailsContentManager.isProgressBarVisible).isFalse()
+    }
+
+    @Test
+    fun updateContent_shareWifiIntentNull_hideButton() {
+        whenever(
+                internetDetailsContentController.getConfiguratorQrCodeGeneratorIntentOrNull(
+                    ArgumentMatchers.any()
+                )
+            )
+            .thenReturn(null)
+        internetDetailsContentManager.updateContent(false)
+        bgExecutor.runAllReady()
+
+        internetDetailsContentManager.internetContentData.observe(
+            internetDetailsContentManager.lifecycleOwner!!
+        ) {
+            assertThat(sharedWifiButton?.visibility).isEqualTo(View.GONE)
+        }
+    }
+
+    @Test
+    fun updateContent_shareWifiShareable_showButton() {
+        whenever(
+                internetDetailsContentController.getConfiguratorQrCodeGeneratorIntentOrNull(
+                    ArgumentMatchers.any()
+                )
+            )
+            .thenReturn(Intent())
+        internetDetailsContentManager.updateContent(false)
+        bgExecutor.runAllReady()
+
+        internetDetailsContentManager.internetContentData.observe(
+            internetDetailsContentManager.lifecycleOwner!!
+        ) {
+            assertThat(sharedWifiButton?.visibility).isEqualTo(View.VISIBLE)
+        }
+    }
+
+    companion object {
+        private const val TITLE = "Internet"
+        private const val MOBILE_NETWORK_TITLE = "Mobile Title"
+        private const val MOBILE_NETWORK_SUMMARY = "Mobile Summary"
+        private const val WIFI_TITLE = "Connected Wi-Fi Title"
+        private const val WIFI_SUMMARY = "Connected Wi-Fi Summary"
+    }
+}
