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

Commit 11f98e2a authored by Franciszek Juras's avatar Franciszek Juras
Browse files

Change package used for adapting layout to window size

androidx.window.core.layout.WindowSizeClass is planned to replace
androidx.compose.material3.windowsizeclass.WindowSizeClass that's used
in SysUI for adapting layout to window size.

This CL changes usage of androidx.compose.material3.windowsizeclass
.WindowSizeClass to androidx.window.core.layout.WindowSizeClass
across SystemUI code while preserving the original logic.

Added benefit of using androidx.window.core.layout.WindowSizeClass
is the avaialability of Large (1200 dp) and Extra-large (1600 dp) width
breakpoints.

Test: existing tests for appropriate features
Flag: EXEMPT PURE_REFACTOR
Bug: 441954375

Change-Id: I701826cc37ea4ef973b2d420da029ff05845fb8f
parent 6fb1c160
Loading
Loading
Loading
Loading
+6 −2
Original line number Diff line number Diff line
@@ -17,13 +17,14 @@
package com.android.compose.windowsizeclass

import androidx.compose.material3.windowsizeclass.ExperimentalMaterial3WindowSizeClassApi
import androidx.compose.material3.windowsizeclass.WindowSizeClass
import androidx.compose.runtime.Composable
import androidx.compose.runtime.staticCompositionLocalOf
import androidx.compose.ui.graphics.toComposeRect
import androidx.compose.ui.platform.LocalConfiguration
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.platform.LocalDensity
import androidx.window.core.layout.WindowSizeClass
import androidx.window.core.layout.computeWindowSizeClass
import androidx.window.layout.WindowMetricsCalculator

val LocalWindowSizeClass =
@@ -43,5 +44,8 @@ fun calculateWindowSizeClass(): WindowSizeClass {
    val context = LocalContext.current
    val metrics = WindowMetricsCalculator.getOrCreate().computeCurrentWindowMetrics(context)
    val size = with(density) { metrics.bounds.toComposeRect().size.toDpSize() }
    return WindowSizeClass.calculateFromSize(size)
    return WindowSizeClass.BREAKPOINTS_V2.computeWindowSizeClass(
        size.width.value,
        size.height.value,
    )
}
+15 −11
Original line number Diff line number Diff line
@@ -23,8 +23,6 @@ import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.PaddingValues
import androidx.compose.foundation.layout.padding
import androidx.compose.material3.windowsizeclass.WindowHeightSizeClass
import androidx.compose.material3.windowsizeclass.WindowWidthSizeClass
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.getValue
@@ -45,7 +43,8 @@ import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.platform.LocalDensity
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.toSize
import com.android.compose.windowsizeclass.calculateWindowSizeClass
import androidx.window.core.layout.WindowSizeClass
import com.android.compose.windowsizeclass.LocalWindowSizeClass
import com.android.systemui.ambientcue.ui.utils.AmbientCueAnimationState
import com.android.systemui.ambientcue.ui.viewmodel.ActionViewModel
import com.android.systemui.ambientcue.ui.viewmodel.AmbientCueViewModel
@@ -141,11 +140,11 @@ private fun TaskBarAnd3ButtonAmbientCue(
    }
    val content = LocalContext.current
    val rotation = content.display.rotation
    val windowWidthSizeClass = calculateWindowSizeClass().widthSizeClass
    val windowHeightSizeClass = calculateWindowSizeClass().heightSizeClass
    val largeScreen =
        (windowWidthSizeClass != WindowWidthSizeClass.Compact &&
            windowHeightSizeClass != WindowHeightSizeClass.Compact)
        LocalWindowSizeClass.current.isAtLeastBreakpoint(
            WindowSizeClass.WIDTH_DP_MEDIUM_LOWER_BOUND,
            WindowSizeClass.HEIGHT_DP_MEDIUM_LOWER_BOUND,
        )

    ActionList(
        actions = actions,
@@ -242,11 +241,16 @@ private fun NavBarAmbientCue(
    modifier: Modifier = Modifier,
    onAnimationStateChange: (Int, AmbientCueAnimationState) -> Unit,
) {
    val windowWidthSizeClass = calculateWindowSizeClass().widthSizeClass

    val navBarWidth =
        if (windowWidthSizeClass == WindowWidthSizeClass.Compact) NAV_BAR_PILL_WIDTH_DP.dp
        else NAV_BAR_PILL_LARGE_WIDTH_DP.dp
        if (
            LocalWindowSizeClass.current.isWidthAtLeastBreakpoint(
                WindowSizeClass.WIDTH_DP_MEDIUM_LOWER_BOUND
            )
        ) {
            NAV_BAR_PILL_LARGE_WIDTH_DP.dp
        } else {
            NAV_BAR_PILL_WIDTH_DP.dp
        }

    val scope = rememberCoroutineScope()

+7 −3
Original line number Diff line number Diff line
@@ -59,7 +59,6 @@ import androidx.compose.material3.Icon
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.OutlinedButton
import androidx.compose.material3.Text
import androidx.compose.material3.windowsizeclass.WindowHeightSizeClass
import androidx.compose.runtime.Composable
import androidx.compose.runtime.DisposableEffect
import androidx.compose.runtime.LaunchedEffect
@@ -94,6 +93,7 @@ import androidx.compose.ui.unit.LayoutDirection
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.times
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import androidx.window.core.layout.WindowSizeClass
import com.android.compose.PlatformButton
import com.android.compose.animation.Easings
import com.android.compose.animation.scene.ContentScope
@@ -297,7 +297,9 @@ private fun StandardLayout(
    modifier: Modifier = Modifier,
) {
    val isHeightExpanded =
        LocalWindowSizeClass.current.heightSizeClass == WindowHeightSizeClass.Expanded
        LocalWindowSizeClass.current.isHeightAtLeastBreakpoint(
            WindowSizeClass.HEIGHT_DP_EXPANDED_LOWER_BOUND
        )

    FoldAware(
        modifier = modifier.padding(top = 92.dp, bottom = 32.dp),
@@ -448,7 +450,9 @@ private fun BesideUserSwitcherLayout(
    // of layout.
    val isSwapped = isLeftToRight == isInputPreferredOnLeftSide
    val isHeightExpanded =
        LocalWindowSizeClass.current.heightSizeClass == WindowHeightSizeClass.Expanded
        LocalWindowSizeClass.current.isHeightAtLeastBreakpoint(
            WindowSizeClass.HEIGHT_DP_EXPANDED_LOWER_BOUND
        )
    val authMethod by viewModel.authMethodViewModel.collectAsStateWithLifecycle()

    var swapAnimationEnd by remember { mutableStateOf(false) }
+19 −52
Original line number Diff line number Diff line
@@ -17,9 +17,8 @@
package com.android.systemui.bouncer.ui.composable

import androidx.annotation.VisibleForTesting
import androidx.compose.material3.windowsizeclass.WindowHeightSizeClass
import androidx.compose.material3.windowsizeclass.WindowWidthSizeClass
import androidx.compose.runtime.Composable
import androidx.window.core.layout.WindowSizeClass
import com.android.compose.windowsizeclass.LocalWindowSizeClass

/**
@@ -29,31 +28,7 @@ import com.android.compose.windowsizeclass.LocalWindowSizeClass
 */
@Composable
fun calculateLayout(isOneHandedModeSupported: Boolean): BouncerOverlayLayout {
    val windowSizeClass = LocalWindowSizeClass.current

    return calculateLayoutInternal(
        width = windowSizeClass.widthSizeClass.toEnum(),
        height = windowSizeClass.heightSizeClass.toEnum(),
        isOneHandedModeSupported = isOneHandedModeSupported,
    )
}

private fun WindowWidthSizeClass.toEnum(): SizeClass {
    return when (this) {
        WindowWidthSizeClass.Compact -> SizeClass.COMPACT
        WindowWidthSizeClass.Medium -> SizeClass.MEDIUM
        WindowWidthSizeClass.Expanded -> SizeClass.EXPANDED
        else -> error("Unsupported WindowWidthSizeClass \"$this\"")
    }
}

private fun WindowHeightSizeClass.toEnum(): SizeClass {
    return when (this) {
        WindowHeightSizeClass.Compact -> SizeClass.COMPACT
        WindowHeightSizeClass.Medium -> SizeClass.MEDIUM
        WindowHeightSizeClass.Expanded -> SizeClass.EXPANDED
        else -> error("Unsupported WindowHeightSizeClass \"$this\"")
    }
    return calculateLayoutInternal(LocalWindowSizeClass.current, isOneHandedModeSupported)
}

/** Enumerates all known adaptive layout configurations. */
@@ -68,37 +43,29 @@ enum class BouncerOverlayLayout {
    SPLIT_BOUNCER,
}

/** Enumerates the supported window size classes. */
enum class SizeClass {
    COMPACT,
    MEDIUM,
    EXPANDED,
}

/**
 * Internal version of `calculateLayout` in the System UI Compose library, extracted here to allow
 * for testing that's not dependent on Compose.
 */
@VisibleForTesting
fun calculateLayoutInternal(
    width: SizeClass,
    height: SizeClass,
    windowSizeClass: WindowSizeClass,
    isOneHandedModeSupported: Boolean,
): BouncerOverlayLayout {
    return when (height) {
        SizeClass.COMPACT -> BouncerOverlayLayout.SPLIT_BOUNCER
        SizeClass.MEDIUM ->
            when (width) {
                SizeClass.COMPACT -> BouncerOverlayLayout.STANDARD_BOUNCER
                SizeClass.MEDIUM -> BouncerOverlayLayout.STANDARD_BOUNCER
                SizeClass.EXPANDED -> BouncerOverlayLayout.BESIDE_USER_SWITCHER
            }
        SizeClass.EXPANDED ->
            when (width) {
                SizeClass.COMPACT -> BouncerOverlayLayout.STANDARD_BOUNCER
                SizeClass.MEDIUM -> BouncerOverlayLayout.BELOW_USER_SWITCHER
                SizeClass.EXPANDED -> BouncerOverlayLayout.BESIDE_USER_SWITCHER
            }
    with(windowSizeClass) {
        return when {
            isAtLeastBreakpoint(
                WindowSizeClass.WIDTH_DP_EXPANDED_LOWER_BOUND,
                WindowSizeClass.HEIGHT_DP_MEDIUM_LOWER_BOUND,
            ) -> BouncerOverlayLayout.BESIDE_USER_SWITCHER
            isAtLeastBreakpoint(
                WindowSizeClass.WIDTH_DP_MEDIUM_LOWER_BOUND,
                WindowSizeClass.HEIGHT_DP_EXPANDED_LOWER_BOUND,
            ) -> BouncerOverlayLayout.BELOW_USER_SWITCHER
            isHeightAtLeastBreakpoint(WindowSizeClass.HEIGHT_DP_MEDIUM_LOWER_BOUND) ->
                BouncerOverlayLayout.STANDARD_BOUNCER
            else -> BouncerOverlayLayout.SPLIT_BOUNCER
        }.takeIf { it != BouncerOverlayLayout.BESIDE_USER_SWITCHER || isOneHandedModeSupported }
            ?: BouncerOverlayLayout.STANDARD_BOUNCER
    }
}
+11 −6
Original line number Diff line number Diff line
@@ -105,8 +105,6 @@ import androidx.compose.material3.ModalBottomSheet
import androidx.compose.material3.OutlinedButton
import androidx.compose.material3.Text
import androidx.compose.material3.rememberModalBottomSheetState
import androidx.compose.material3.windowsizeclass.WindowHeightSizeClass
import androidx.compose.material3.windowsizeclass.WindowWidthSizeClass
import androidx.compose.runtime.Composable
import androidx.compose.runtime.CompositionLocalProvider
import androidx.compose.runtime.LaunchedEffect
@@ -178,6 +176,7 @@ import androidx.compose.ui.viewinterop.AndroidView
import androidx.compose.ui.viewinterop.NoOpUpdate
import androidx.compose.ui.zIndex
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import androidx.window.core.layout.WindowSizeClass
import androidx.window.layout.WindowMetricsCalculator
import com.android.compose.animation.Easings.Emphasized
import com.android.compose.animation.scene.ContentScope
@@ -2082,8 +2081,10 @@ private fun gridContentPadding(isEditMode: Boolean, toolbarSize: IntSize?): Padd
fun isCompactWindow(): Boolean {
    val windowSizeClass = LocalWindowSizeClass.current
    return remember(windowSizeClass) {
        windowSizeClass.widthSizeClass == WindowWidthSizeClass.Compact ||
            windowSizeClass.heightSizeClass == WindowHeightSizeClass.Compact
        !windowSizeClass.isAtLeastBreakpoint(
            WindowSizeClass.WIDTH_DP_MEDIUM_LOWER_BOUND,
            WindowSizeClass.HEIGHT_DP_MEDIUM_LOWER_BOUND,
        )
    }
}

@@ -2092,8 +2093,12 @@ fun isCompactWindow(): Boolean {
private fun isMediumWindow(): Boolean {
    val windowSizeClass = LocalWindowSizeClass.current
    return remember(windowSizeClass) {
        windowSizeClass.widthSizeClass == WindowWidthSizeClass.Medium ||
            windowSizeClass.heightSizeClass == WindowHeightSizeClass.Medium
        with(windowSizeClass) {
            (isWidthAtLeastBreakpoint(WindowSizeClass.WIDTH_DP_MEDIUM_LOWER_BOUND) &&
                !isWidthAtLeastBreakpoint(WindowSizeClass.WIDTH_DP_EXPANDED_LOWER_BOUND)) ||
                (isHeightAtLeastBreakpoint(WindowSizeClass.HEIGHT_DP_MEDIUM_LOWER_BOUND) &&
                    !isHeightAtLeastBreakpoint(WindowSizeClass.HEIGHT_DP_EXPANDED_LOWER_BOUND))
        }
    }
}

Loading