Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -98,8 +98,39 @@ import java.util.concurrent.atomic.AtomicReference
class SheetInteractionTest {
private val device get() = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation())

@Test
fun sheetInheritsHiddenStatusBarOnLegacyAndroid() {
assumeTrue(Build.VERSION.SDK_INT < 30)
// On API 29 and below, inspect System UI itself so the assertion cannot repeat the
// compat insets misreading that this regression test is intended to catch.
val statusBar = By.res("com.android.systemui", "status_bar")
for (displayMode in listOf(SheetDisplayMode.Bottom, SheetDisplayMode.Floating)) {
val fixture = AndroidSheetFixture(displayMode = displayMode)
ActivityScenario.launch(MainActivity::class.java).use { scenario ->
scenario.onActivity { activity ->
WindowCompat.getInsetsController(activity.window, activity.window.decorView)
.hide(WindowInsetsCompat.Type.statusBars())
activity.setContent { fixture.Content() }
}
shown(By.text("Open sheet"))
assertTrue(device.wait(Until.gone(statusBar), 5_000))
click(By.text("Open sheet"))
shown(By.text("Fixture sheet"))
assertTrue(device.wait(Until.gone(statusBar), 5_000))
click(By.text("Inside"))
shown(By.text("Inside: 1"))
assertTrue(device.wait(Until.gone(statusBar), 5_000))
click(By.text("Program close"))
assertTrue(device.wait(Until.gone(By.text("Fixture sheet")), 5_000))
}
}
}

@Test
fun sheetInheritsSystemBarsAndAllowsContentToManageThem() {
// On Android 10 (API 29) and earlier, dialog focus can clear the owner's hide flags.
// Opening inheritance is tested separately there; this full isolation check needs API 30+.
assumeTrue(Build.VERSION.SDK_INT >= 30)
val statusBar = WindowInsetsCompat.Type.statusBars()
val navigationBar = WindowInsetsCompat.Type.navigationBars()
for (displayMode in listOf(SheetDisplayMode.Bottom, SheetDisplayMode.Floating)) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,16 +21,19 @@ package com.moriafly.salt.ui.sheet.internal

import android.view.View
import android.view.Window
import androidx.core.view.ViewCompat
import androidx.core.view.WindowCompat
import androidx.core.view.WindowInsetsCompat

/**
* Initializes one Sheet dialog window with the owner's opening system bar visibility.
*
* Call [inheritOwnerVisibility] from the host's SideEffect after a successful composition.
* Only the dialog's controller is changed; the owner keeps its own requests, so dismissal requires
* no restoration. Further visibility changes belong to the developer controlling the dialog.
* Only the dialog's controller is changed. On Android 10 (API 29) and earlier, the platform can
* propagate cleared system UI flags to other windows during focus changes, removing the owner's
* hide requests. Restoring the opening snapshot could overwrite newer host requests, so no
* restoration is done on dismissal.
* On these versions, immersive hosts should reapply their current visibility when focus returns.
* Further visibility changes belong to the developer controlling the dialog.
*/
internal class SheetSystemBars(
window: Window,
Expand Down Expand Up @@ -72,7 +75,12 @@ internal class SheetSystemBars(
* uses the platform's default visible bars.
*/
fun readOwnerVisibility(ownerView: View): Visibility {
val insets = ViewCompat.getRootWindowInsets(ownerView)
// On Android 6–10 (API 23–29), root insets can retain layout space for hidden bars.
// ViewCompat.getRootWindowInsets() omits the window's system UI flags during conversion,
// so isVisible() can mistake that space for visible bars. Passing the View includes
// the window's hide flags in the calculation. API 30+ uses native visibility instead.
val insets = ownerView.rootWindowInsets
?.let { WindowInsetsCompat.toWindowInsetsCompat(it, ownerView) }
return Visibility(
statusBarVisible = insets?.isVisible(WindowInsetsCompat.Type.statusBars()) != false,
navigationBarVisible =
Expand Down
Loading