Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 58bf2b4f authored by Jiaming Cheng's avatar Jiaming Cheng Committed by Android (Google) Code Review
Browse files

Merge "[QSDetailedView] Integrate InternetDetailsContentManager with...

Merge "[QSDetailedView] Integrate InternetDetailsContentManager with InternetDetailsViewModel and InternetTileUserActionInteractor ( qs_new_tiles enabled)" into main
parents f04ff3ec f896b920
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -37,6 +37,7 @@ import com.android.systemui.qs.QsEventLogger
import com.android.systemui.qs.flags.QSComposeFragment
import com.android.systemui.qs.flags.QsDetailedView
import com.android.systemui.qs.logging.QSLogger
import com.android.systemui.qs.tiles.dialog.InternetDetailsViewModel
import com.android.systemui.qs.tiles.dialog.InternetDialogManager
import com.android.systemui.qs.tiles.dialog.WifiStateWorker
import com.android.systemui.res.R
@@ -109,6 +110,7 @@ class InternetTileNewImplTest(flags: FlagsParameterization) : SysuiTestCase() {
    @Mock private lateinit var dialogManager: InternetDialogManager
    @Mock private lateinit var wifiStateWorker: WifiStateWorker
    @Mock private lateinit var accessPointController: AccessPointController
    @Mock private lateinit var internetDetailsViewModelFactory: InternetDetailsViewModel.Factory

    @Before
    fun setUp() {
@@ -145,6 +147,7 @@ class InternetTileNewImplTest(flags: FlagsParameterization) : SysuiTestCase() {
                dialogManager,
                wifiStateWorker,
                accessPointController,
                internetDetailsViewModelFactory
            )

        underTest.initialize()
+24 −11
Original line number Diff line number Diff line
@@ -26,13 +26,13 @@ import com.android.systemui.kosmos.testScope
import com.android.systemui.qs.tiles.base.actions.FakeQSTileIntentUserInputHandler
import com.android.systemui.qs.tiles.base.actions.QSTileIntentUserInputHandlerSubject
import com.android.systemui.qs.tiles.base.interactor.QSTileInputTestKtx
import com.android.systemui.qs.tiles.dialog.InternetDetailsContentManager
import com.android.systemui.qs.tiles.dialog.InternetDetailsViewModel
import com.android.systemui.qs.tiles.dialog.InternetDialogManager
import com.android.systemui.qs.tiles.dialog.WifiStateWorker
import com.android.systemui.qs.tiles.impl.internet.domain.model.InternetTileModel
import com.android.systemui.statusbar.connectivity.AccessPointController
import com.android.systemui.util.mockito.mock
import com.android.systemui.util.mockito.nullable
import com.google.common.truth.Truth
import com.google.common.truth.Truth.assertThat
import kotlinx.coroutines.test.runTest
import org.junit.Before
@@ -40,9 +40,10 @@ import org.junit.Test
import org.junit.runner.RunWith
import org.mockito.ArgumentMatchers.anyBoolean
import org.mockito.ArgumentMatchers.eq
import org.mockito.Mock
import org.mockito.Mockito.verify
import org.mockito.kotlin.any
import org.mockito.kotlin.mock
import org.mockito.kotlin.times
import org.mockito.kotlin.verify
import org.mockito.kotlin.whenever

@SmallTest
@@ -54,15 +55,27 @@ class InternetTileUserActionInteractorTest : SysuiTestCase() {

    private lateinit var underTest: InternetTileUserActionInteractor

    @Mock private lateinit var internetDialogManager: InternetDialogManager
    @Mock private lateinit var wifiStateWorker: WifiStateWorker
    @Mock private lateinit var controller: AccessPointController
    private lateinit var internetDialogManager: InternetDialogManager
    private lateinit var wifiStateWorker: WifiStateWorker
    private lateinit var controller: AccessPointController
    private lateinit var internetDetailsViewModelFactory: InternetDetailsViewModel.Factory
    private lateinit var internetDetailsContentManagerFactory: InternetDetailsContentManager.Factory
    private lateinit var internetDetailsViewModel: InternetDetailsViewModel

    @Before
    fun setup() {
        internetDialogManager = mock<InternetDialogManager>()
        wifiStateWorker = mock<WifiStateWorker>()
        controller = mock<AccessPointController>()
        internetDetailsViewModelFactory = mock<InternetDetailsViewModel.Factory>()
        internetDetailsContentManagerFactory = mock<InternetDetailsContentManager.Factory>()
        internetDetailsViewModel =
            InternetDetailsViewModel(
                onLongClick = {},
                accessPointController = mock<AccessPointController>(),
                contentManagerFactory = internetDetailsContentManagerFactory,
            )
        whenever(internetDetailsViewModelFactory.create(any())).thenReturn(internetDetailsViewModel)

        underTest =
            InternetTileUserActionInteractor(
@@ -71,6 +84,7 @@ class InternetTileUserActionInteractorTest : SysuiTestCase() {
                wifiStateWorker,
                controller,
                inputHandler,
                internetDetailsViewModelFactory,
            )
    }

@@ -102,7 +116,7 @@ class InternetTileUserActionInteractorTest : SysuiTestCase() {
            underTest.handleInput(QSTileInputTestKtx.longClick(input))

            QSTileIntentUserInputHandlerSubject.assertThat(inputHandler).handledOneIntentInput {
                Truth.assertThat(it.intent.action).isEqualTo(Settings.ACTION_WIFI_SETTINGS)
                assertThat(it.intent.action).isEqualTo(Settings.ACTION_WIFI_SETTINGS)
            }
        }

@@ -114,7 +128,7 @@ class InternetTileUserActionInteractorTest : SysuiTestCase() {
            underTest.handleInput(QSTileInputTestKtx.longClick(input))

            QSTileIntentUserInputHandlerSubject.assertThat(inputHandler).handledOneIntentInput {
                Truth.assertThat(it.intent.action).isEqualTo(Settings.ACTION_WIFI_SETTINGS)
                assertThat(it.intent.action).isEqualTo(Settings.ACTION_WIFI_SETTINGS)
            }
        }

@@ -141,8 +155,7 @@ class InternetTileUserActionInteractorTest : SysuiTestCase() {
    @Test
    fun detailsViewModel() =
        kosmos.testScope.runTest {
            assertThat(underTest.detailsViewModel.getTitle())
                .isEqualTo("Internet")
            assertThat(underTest.detailsViewModel.getTitle()).isEqualTo("Internet")
            assertThat(underTest.detailsViewModel.getSubTitle())
                .isEqualTo("Tab a network to connect")
        }
+2 −1
Original line number Diff line number Diff line
@@ -61,6 +61,7 @@ constructor(
    private val internetDialogManager: InternetDialogManager,
    private val wifiStateWorker: WifiStateWorker,
    private val accessPointController: AccessPointController,
    private val internetDetailsViewModelFactory: InternetDetailsViewModel.Factory,
) :
    QSTileImpl<QSTile.BooleanState>(
        host,
@@ -107,7 +108,7 @@ constructor(
    }

    override fun getDetailsViewModel(): TileDetailsViewModel {
        return InternetDetailsViewModel { longClick(null) }
        return internetDetailsViewModelFactory.create { longClick(null) }
    }

    override fun handleSecondaryClick(expandable: Expandable?) {
+22 −59
Original line number Diff line number Diff line
@@ -57,10 +57,8 @@ import com.android.settingslib.satellite.SatelliteDialogUtils.mayStartSatelliteW
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
@@ -75,11 +73,7 @@ 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(
@@ -88,9 +82,7 @@ constructor(
    @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,
@@ -104,8 +96,6 @@ constructor(

    // 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
@@ -132,7 +122,6 @@ constructor(
    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)
@@ -153,7 +142,6 @@ constructor(
            @Assisted(CAN_CONFIG_WIFI) canConfigWifi: Boolean,
            coroutineScope: CoroutineScope,
            context: Context,
            internetDialog: SystemUIDialog?,
        ): InternetDetailsContentManager
    }

@@ -209,8 +197,6 @@ constructor(
        }

        // 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)

@@ -219,15 +205,6 @@ constructor(
        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 ->
@@ -251,6 +228,17 @@ constructor(
        // Background drawables
        backgroundOn = context.getDrawable(R.drawable.settingslib_switch_bar_bg_on)
        backgroundOff = context.getDrawable(R.drawable.internet_dialog_selected_effect)

        // Done button is only visible for the dialog view
        contentView.findViewById<Button>(R.id.done_button).apply { visibility = View.GONE }

        // Title and subtitle will be added in the `TileDetails`
        contentView.findViewById<TextView>(R.id.internet_dialog_title).apply {
            visibility = View.GONE
        }
        contentView.findViewById<TextView>(R.id.internet_dialog_subtitle).apply {
            visibility = View.GONE
        }
    }

    private fun setWifiLayout() {
@@ -336,21 +324,19 @@ constructor(
        }
    }

    private fun getDialogTitleText(): CharSequence {
        return internetDetailsContentController.getDialogTitleText()
    fun getTitleText(): String {
        return internetDetailsContentController.getDialogTitleText().toString()
    }

    fun getSubtitleText(): String {
        return internetDetailsContentController.getSubtitleText(isProgressBarVisible).toString()
    }

    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

@@ -361,17 +347,11 @@ constructor(

    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)
@@ -393,7 +373,6 @@ constructor(
        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) {
@@ -418,12 +397,7 @@ constructor(
        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 {
@@ -466,11 +440,8 @@ constructor(
        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?) {
@@ -803,7 +774,6 @@ constructor(
        secondaryMobileNetworkLayout?.setOnClickListener(null)
        seeAllLayout.setOnClickListener(null)
        wifiToggle.setOnCheckedChangeListener(null)
        doneButton.setOnClickListener(null)
        shareWifiButton.setOnClickListener(null)
        airplaneModeButton.setOnClickListener(null)
        internetDetailsContentController.onStop()
@@ -825,8 +795,6 @@ constructor(
    private fun getInternetContent(shouldUpdateMobileNetwork: Boolean): InternetContent {
        return InternetContent(
            shouldUpdateMobileNetwork = shouldUpdateMobileNetwork,
            internetDialogTitleString = getDialogTitleText(),
            internetDialogSubTitle = getSubtitleText(),
            activeNetworkIsCellular =
                if (shouldUpdateMobileNetwork)
                    internetDetailsContentController.activeNetworkIsCellular()
@@ -924,10 +892,7 @@ constructor(
                if (DEBUG) {
                    Log.d(TAG, "dismissDialog")
                }
                if (internetDialog != null) {
                    internetDialog!!.dismiss()
                    internetDialog = null
                }
                // TODO: b/377388104 Close details view
            }

            override fun onAccessPointsChanged(
@@ -967,8 +932,6 @@ constructor(

    @VisibleForTesting
    data class InternetContent(
        val internetDialogTitleString: CharSequence,
        val internetDialogSubTitle: CharSequence,
        val isAirplaneModeEnabled: Boolean = false,
        val hasEthernet: Boolean = false,
        val shouldUpdateMobileNetwork: Boolean = false,
+57 −8
Original line number Diff line number Diff line
@@ -16,44 +16,93 @@

package com.android.systemui.qs.tiles.dialog

import android.util.Log
import android.view.LayoutInflater
import androidx.compose.foundation.layout.fillMaxHeight
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.runtime.Composable
import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.viewinterop.AndroidView
import com.android.systemui.plugins.qs.TileDetailsViewModel
import com.android.systemui.res.R
import com.android.systemui.statusbar.connectivity.AccessPointController
import dagger.assisted.Assisted
import dagger.assisted.AssistedFactory
import dagger.assisted.AssistedInject

class InternetDetailsViewModel(
    onLongClick: () -> Unit,
class InternetDetailsViewModel
@AssistedInject
constructor(
    private val accessPointController: AccessPointController,
    private val contentManagerFactory: InternetDetailsContentManager.Factory,
    @Assisted private val onLongClick: () -> Unit,
) : TileDetailsViewModel() {
    private val _onLongClick = onLongClick
    private lateinit var internetDetailsContentManager: InternetDetailsContentManager

    @Composable
    override fun GetContentView() {
        val coroutineScope = rememberCoroutineScope()
        val context = LocalContext.current

        internetDetailsContentManager = remember {
            contentManagerFactory.create(
                canConfigMobileData = accessPointController.canConfigMobileData(),
                canConfigWifi = accessPointController.canConfigWifi(),
                coroutineScope = coroutineScope,
                context = context,
            )
        }
        AndroidView(
            modifier = Modifier.fillMaxWidth().fillMaxHeight(),
            factory = { context ->
                // Inflate with the existing dialog xml layout
                // Inflate with the existing dialog xml layout and bind it with the manager
                val view =
                    LayoutInflater.from(context)
                        .inflate(R.layout.internet_connectivity_dialog, null)
                // TODO: b/377388104 - Implement the internet details view
                internetDetailsContentManager.bind(view)

                view
                // TODO: b/377388104 - Polish the internet details view UI
            },
            onRelease = {
                internetDetailsContentManager.unBind()
                if (DEBUG) {
                    Log.d(TAG, "onRelease")
                }
            },
        )
    }

    override fun clickOnSettingsButton() {
        _onLongClick()
        onLongClick()
    }

    override fun getTitle(): String {
        // TODO: b/377388104 make title and sub title mutable states of string
        // by internetDetailsContentManager.getTitleText()
        // TODO: test title change between airplane mode and not airplane mode
        // TODO: b/377388104 Update the placeholder text
        return "Internet"
    }

    override fun getSubTitle(): String {
        // TODO: b/377388104 make title and sub title mutable states of string
        // by internetDetailsContentManager.getSubtitleText()
        // TODO: test subtitle change between airplane mode and not airplane mode
        // TODO: b/377388104 Update the placeholder text
        return "Tab a network to connect"
    }

    @AssistedFactory
    interface Factory {
        fun create(onLongClick: () -> Unit): InternetDetailsViewModel
    }

    companion object {
        private const val TAG = "InternetDetailsVModel"
        private val DEBUG: Boolean = Log.isLoggable(TAG, Log.DEBUG)
    }
}
Loading