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

Commit cf745080 authored by Olivier St-Onge's avatar Olivier St-Onge Committed by Android (Google) Code Review
Browse files

Merge "Wire up secondary clicks to tiles" into main

parents aba7df49 d7bbb75b
Loading
Loading
Loading
Loading
+5 −1
Original line number Diff line number Diff line
@@ -117,7 +117,11 @@ class InternetTileMapperTest : SysuiTestCase() {
            label,
            activationState,
            secondaryLabel,
            setOf(QSTileState.UserAction.CLICK, QSTileState.UserAction.LONG_CLICK),
            setOf(
                QSTileState.UserAction.CLICK,
                QSTileState.UserAction.TOGGLE_CLICK,
                QSTileState.UserAction.LONG_CLICK
            ),
            contentDescription,
            null,
            QSTileState.SideViewIcon.Chevron,
+26 −0
Original line number Diff line number Diff line
@@ -27,6 +27,7 @@ import com.android.systemui.qs.tiles.base.actions.FakeQSTileIntentUserInputHandl
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.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
@@ -40,6 +41,8 @@ import org.mockito.ArgumentMatchers.anyBoolean
import org.mockito.ArgumentMatchers.eq
import org.mockito.Mock
import org.mockito.Mockito.verify
import org.mockito.kotlin.times
import org.mockito.kotlin.whenever

@SmallTest
@EnabledOnRavenwood
@@ -51,17 +54,20 @@ 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

    @Before
    fun setup() {
        internetDialogManager = mock<InternetDialogManager>()
        wifiStateWorker = mock<WifiStateWorker>()
        controller = mock<AccessPointController>()

        underTest =
            InternetTileUserActionInteractor(
                kosmos.testScope.coroutineContext,
                internetDialogManager,
                wifiStateWorker,
                controller,
                inputHandler,
            )
@@ -110,4 +116,24 @@ class InternetTileUserActionInteractorTest : SysuiTestCase() {
                Truth.assertThat(it.intent.action).isEqualTo(Settings.ACTION_WIFI_SETTINGS)
            }
        }

    @Test
    fun handleSecondaryClickWhenWifiOn() =
        kosmos.testScope.runTest {
            whenever(wifiStateWorker.isWifiEnabled).thenReturn(true)

            underTest.handleInput(QSTileInputTestKtx.toggleClick(InternetTileModel.Active()))

            verify(wifiStateWorker, times(1)).isWifiEnabled = eq(false)
        }

    @Test
    fun handleSecondaryClickWhenWifiOff() =
        kosmos.testScope.runTest {
            whenever(wifiStateWorker.isWifiEnabled).thenReturn(false)

            underTest.handleInput(QSTileInputTestKtx.toggleClick(InternetTileModel.Inactive()))

            verify(wifiStateWorker, times(1)).isWifiEnabled = eq(true)
        }
}
+4 −0
Original line number Diff line number Diff line
@@ -169,6 +169,7 @@ public interface QSTile {
        public boolean isTransient = false;
        public String expandedAccessibilityClassName;
        public boolean handlesLongClick = true;
        public boolean handlesSecondaryClick = false;
        @Nullable
        public Drawable sideViewCustomDrawable;
        public String spec;
@@ -212,6 +213,7 @@ public interface QSTile {
                    || !Objects.equals(other.isTransient, isTransient)
                    || !Objects.equals(other.dualTarget, dualTarget)
                    || !Objects.equals(other.handlesLongClick, handlesLongClick)
                    || !Objects.equals(other.handlesSecondaryClick, handlesSecondaryClick)
                    || !Objects.equals(other.sideViewCustomDrawable, sideViewCustomDrawable);
            other.spec = spec;
            other.icon = icon;
@@ -227,6 +229,7 @@ public interface QSTile {
            other.dualTarget = dualTarget;
            other.isTransient = isTransient;
            other.handlesLongClick = handlesLongClick;
            other.handlesSecondaryClick = handlesSecondaryClick;
            other.sideViewCustomDrawable = sideViewCustomDrawable;
            return changed;
        }
@@ -252,6 +255,7 @@ public interface QSTile {
            sb.append(",disabledByPolicy=").append(disabledByPolicy);
            sb.append(",dualTarget=").append(dualTarget);
            sb.append(",isTransient=").append(isTransient);
            sb.append(",handlesSecondaryClick=").append(handlesSecondaryClick);
            sb.append(",state=").append(state);
            sb.append(",sideViewCustomDrawable=").append(sideViewCustomDrawable);
            return sb.append(']');
+45 −31
Original line number Diff line number Diff line
@@ -109,6 +109,7 @@ import com.android.systemui.qs.panels.ui.model.GridCell
import com.android.systemui.qs.panels.ui.model.SpacerGridCell
import com.android.systemui.qs.panels.ui.model.TileGridCell
import com.android.systemui.qs.panels.ui.viewmodel.EditTileViewModel
import com.android.systemui.qs.panels.ui.viewmodel.TileUiState
import com.android.systemui.qs.panels.ui.viewmodel.TileViewModel
import com.android.systemui.qs.panels.ui.viewmodel.toUiState
import com.android.systemui.qs.pipeline.domain.interactor.CurrentTilesInteractor
@@ -129,7 +130,7 @@ fun Tile(
) {
    val state by tile.state.collectAsStateWithLifecycle(tile.currentState)
    val uiState = remember(state) { state.toUiState() }
    val colors = TileDefaults.getColorForState(uiState.state)
    val colors = TileDefaults.getColorForState(uiState)

    TileContainer(
        colors = colors,
@@ -150,9 +151,13 @@ fun Tile(
                secondaryLabel = uiState.secondaryLabel,
                icon = icon,
                colors = colors,
                clickEnabled = true,
                onClick = tile::onSecondaryClick,
                onLongClick = tile::onLongClick,
                toggleClickSupported = state.handlesSecondaryClick,
                onClick = {
                    if (state.handlesSecondaryClick) {
                        tile.onSecondaryClick()
                    }
                },
                onLongClick = { tile.onLongClick(it) },
            )
        }
    }
@@ -168,7 +173,7 @@ private fun TileContainer(
    onClick: (Expandable) -> Unit = {},
    onLongClick: (Expandable) -> Unit = {},
    modifier: Modifier = Modifier,
    content: @Composable BoxScope.() -> Unit,
    content: @Composable BoxScope.(Expandable) -> Unit,
) {
    Column(
        horizontalAlignment = Alignment.CenterHorizontally,
@@ -200,7 +205,7 @@ private fun TileContainer(
                        }
                        .tilePadding(),
            ) {
                content()
                content(it)
            }
        }

@@ -222,36 +227,27 @@ private fun LargeTileContent(
    secondaryLabel: String?,
    icon: Icon,
    colors: TileColors,
    clickEnabled: Boolean = false,
    onClick: (Expandable) -> Unit = {},
    onLongClick: (Expandable) -> Unit = {},
    toggleClickSupported: Boolean = false,
    onClick: () -> Unit = {},
    onLongClick: () -> Unit = {},
) {
    Row(
        verticalAlignment = Alignment.CenterVertically,
        horizontalArrangement = tileHorizontalArrangement()
    ) {
        Expandable(
            color = colors.iconBackground,
            shape = TileDefaults.TileShape,
            modifier = Modifier.fillMaxHeight().aspectRatio(1f)
        ) {
        // Icon
        Box(
            modifier =
                    Modifier.fillMaxSize().clip(TileDefaults.TileShape).thenIf(clickEnabled) {
                        Modifier.combinedClickable(
                            onClick = { onClick(it) },
                            onLongClick = { onLongClick(it) }
                        )
                Modifier.fillMaxHeight().aspectRatio(1f).thenIf(toggleClickSupported) {
                    Modifier.clip(TileDefaults.TileShape)
                        .background(colors.iconBackground, { 1f })
                        .combinedClickable(onClick = onClick, onLongClick = onLongClick)
                }
        ) {
                TileIcon(
                    icon = icon,
                    color = colors.icon,
                    modifier = Modifier.align(Alignment.Center)
                )
            }
            TileIcon(icon = icon, color = colors.icon, modifier = Modifier.align(Alignment.Center))
        }

        // Labels
        Column(verticalArrangement = Arrangement.Center, modifier = Modifier.fillMaxHeight()) {
            Text(
                label,
@@ -743,8 +739,20 @@ private object TileDefaults {
    val TileShape = CircleShape
    val IconTileWithLabelHeight = 140.dp

    /** An active tile without dual target uses the active color as background */
    @Composable
    fun activeTileColors(): TileColors =
        TileColors(
            background = MaterialTheme.colorScheme.primary,
            iconBackground = MaterialTheme.colorScheme.primary,
            label = MaterialTheme.colorScheme.onPrimary,
            secondaryLabel = MaterialTheme.colorScheme.onPrimary,
            icon = MaterialTheme.colorScheme.onPrimary,
        )

    /** An active tile with dual target only show the active color on the icon */
    @Composable
    fun activeDualTargetTileColors(): TileColors =
        TileColors(
            background = MaterialTheme.colorScheme.surfaceVariant,
            iconBackground = MaterialTheme.colorScheme.primary,
@@ -774,9 +782,15 @@ private object TileDefaults {
        )

    @Composable
    fun getColorForState(state: Int): TileColors {
        return when (state) {
            STATE_ACTIVE -> activeTileColors()
    fun getColorForState(uiState: TileUiState): TileColors {
        return when (uiState.state) {
            STATE_ACTIVE -> {
                if (uiState.handlesSecondaryClick) {
                    activeDualTargetTileColors()
                } else {
                    activeTileColors()
                }
            }
            STATE_INACTIVE -> inactiveTileColors()
            else -> unavailableTileColors()
        }
+2 −0
Original line number Diff line number Diff line
@@ -25,6 +25,7 @@ data class TileUiState(
    val label: String,
    val secondaryLabel: String,
    val state: Int,
    val handlesSecondaryClick: Boolean,
    val icon: Supplier<QSTile.Icon?>,
)

@@ -33,6 +34,7 @@ fun QSTile.State.toUiState(): TileUiState {
        label?.toString() ?: "",
        secondaryLabel?.toString() ?: "",
        state,
        handlesSecondaryClick,
        icon?.let { Supplier { icon } } ?: iconSupplier ?: Supplier { null },
    )
}
Loading