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

Commit 0ca2c59b authored by Franciszek Juras's avatar Franciszek Juras Committed by Android (Google) Code Review
Browse files

Merge changes from topic "window-size-class-refactor" into main

* changes:
  Adapt BouncerOverlayLayoutTest after replacing WindowSizeClass
  Change package used for adapting layout to window size
parents 78b080c7 ad0be88b
Loading
Loading
Loading
Loading
+6 −2
Original line number Original line Diff line number Diff line
@@ -17,13 +17,14 @@
package com.android.compose.windowsizeclass
package com.android.compose.windowsizeclass


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


val LocalWindowSizeClass =
val LocalWindowSizeClass =
@@ -43,5 +44,8 @@ fun calculateWindowSizeClass(): WindowSizeClass {
    val context = LocalContext.current
    val context = LocalContext.current
    val metrics = WindowMetricsCalculator.getOrCreate().computeCurrentWindowMetrics(context)
    val metrics = WindowMetricsCalculator.getOrCreate().computeCurrentWindowMetrics(context)
    val size = with(density) { metrics.bounds.toComposeRect().size.toDpSize() }
    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 Original line 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.Box
import androidx.compose.foundation.layout.PaddingValues
import androidx.compose.foundation.layout.PaddingValues
import androidx.compose.foundation.layout.padding
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.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.getValue
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.platform.LocalDensity
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.toSize
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.utils.AmbientCueAnimationState
import com.android.systemui.ambientcue.ui.viewmodel.ActionViewModel
import com.android.systemui.ambientcue.ui.viewmodel.ActionViewModel
import com.android.systemui.ambientcue.ui.viewmodel.AmbientCueViewModel
import com.android.systemui.ambientcue.ui.viewmodel.AmbientCueViewModel
@@ -141,11 +140,11 @@ private fun TaskBarAnd3ButtonAmbientCue(
    }
    }
    val content = LocalContext.current
    val content = LocalContext.current
    val rotation = content.display.rotation
    val rotation = content.display.rotation
    val windowWidthSizeClass = calculateWindowSizeClass().widthSizeClass
    val windowHeightSizeClass = calculateWindowSizeClass().heightSizeClass
    val largeScreen =
    val largeScreen =
        (windowWidthSizeClass != WindowWidthSizeClass.Compact &&
        LocalWindowSizeClass.current.isAtLeastBreakpoint(
            windowHeightSizeClass != WindowHeightSizeClass.Compact)
            WindowSizeClass.WIDTH_DP_MEDIUM_LOWER_BOUND,
            WindowSizeClass.HEIGHT_DP_MEDIUM_LOWER_BOUND,
        )


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

    val navBarWidth =
    val navBarWidth =
        if (windowWidthSizeClass == WindowWidthSizeClass.Compact) NAV_BAR_PILL_WIDTH_DP.dp
        if (
        else NAV_BAR_PILL_LARGE_WIDTH_DP.dp
            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()
    val scope = rememberCoroutineScope()


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


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


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


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


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

    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\"")
    }
}
}


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


@@ -2092,8 +2093,12 @@ fun isCompactWindow(): Boolean {
private fun isMediumWindow(): Boolean {
private fun isMediumWindow(): Boolean {
    val windowSizeClass = LocalWindowSizeClass.current
    val windowSizeClass = LocalWindowSizeClass.current
    return remember(windowSizeClass) {
    return remember(windowSizeClass) {
        windowSizeClass.widthSizeClass == WindowWidthSizeClass.Medium ||
        with(windowSizeClass) {
            windowSizeClass.heightSizeClass == WindowHeightSizeClass.Medium
            (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